diff --git a/config/app.php b/config/app.php index d783633ab..c564ada25 100644 --- a/config/app.php +++ b/config/app.php @@ -42,7 +42,7 @@ return [ */ 'url' => env('APP_URL', 'http://localhost'), - + 'cdn' => env('CDN_URL','http://cdn.orient.tm'), /* |-------------------------------------------------------------------------- | Application Timezone @@ -81,7 +81,7 @@ return [ | */ - 'locale' => 'en', + 'locale' => 'ru', /* |-------------------------------------------------------------------------- diff --git a/config/cms.php b/config/cms.php index afcde7d79..32395167e 100644 --- a/config/cms.php +++ b/config/cms.php @@ -80,7 +80,7 @@ return [ | */ - 'backendTimezone' => 'UTC', + 'backendTimezone' => 'Asia/Ashgabat', /* |-------------------------------------------------------------------------- @@ -396,7 +396,7 @@ return [ | */ - 'enableCsrfProtection' => env('ENABLE_CSRF', false), + 'enableCsrfProtection' => env('ENABLE_CSRF', true), /* |-------------------------------------------------------------------------- diff --git a/config/logging.php b/config/logging.php index 900d48123..041e80a31 100644 --- a/config/logging.php +++ b/config/logging.php @@ -13,7 +13,7 @@ return [ | */ - 'default' => env('LOG_CHANNEL', 'single'), + 'default' => env('LOG_CHANNEL', 'daily'), /* |-------------------------------------------------------------------------- diff --git a/config/session.php b/config/session.php index 2b48b18d4..b0d0d63a4 100644 --- a/config/session.php +++ b/config/session.php @@ -109,7 +109,7 @@ return [ | */ - 'cookie' => 'october_session', + 'cookie' => 'orient_session', /* |-------------------------------------------------------------------------- diff --git a/modules/system/classes/UpdateManager.php b/modules/system/classes/UpdateManager.php index 7e4779de1..8673a5a7b 100644 --- a/modules/system/classes/UpdateManager.php +++ b/modules/system/classes/UpdateManager.php @@ -234,8 +234,8 @@ class UpdateManager $params = [ 'core' => $this->getHash(), - 'plugins' => serialize($versions), - 'themes' => serialize($themes), + 'plugins' => base64_encode(json_encode($versions)), + 'themes' => base64_encode(json_encode($themes)), 'build' => $build, 'force' => $force ]; @@ -590,8 +590,9 @@ class UpdateManager { $fileCode = $name . $hash; $filePath = $this->getFilePath($fileCode); + $innerPath = str_replace('.', '/', strtolower($name)); - if (!Zip::extract($filePath, plugins_path())) { + if (!Zip::extract($filePath, plugins_path($innerPath))) { throw new ApplicationException(Lang::get('system::lang.zip.extract_failed', ['file' => $filePath])); } @@ -632,8 +633,9 @@ class UpdateManager { $fileCode = $name . $hash; $filePath = $this->getFilePath($fileCode); + $innerPath = str_replace('.', '-', strtolower($name)); - if (!Zip::extract($filePath, themes_path())) { + if (!Zip::extract($filePath, themes_path($innerPath))) { throw new ApplicationException(Lang::get('system::lang.zip.extract_failed', ['file' => $filePath])); } @@ -903,13 +905,16 @@ class UpdateManager $http->toFile($filePath); }); - if ($result->code != 200) { - throw new ApplicationException(File::get($filePath)); + if (in_array($result->code, [301, 302])) { + if ($redirectUrl = array_get($result->info, 'redirect_url')) { + $result = Http::get($redirectUrl, function ($http) use ($postData, $filePath) { + $http->toFile($filePath); + }); + } } - if (md5_file($filePath) != $expectedHash) { - @unlink($filePath); - throw new ApplicationException(Lang::get('system::lang.server.file_corrupt')); + if ($result->code != 200) { + throw new ApplicationException(File::get($filePath)); } } @@ -942,7 +947,7 @@ class UpdateManager */ protected function createServerUrl($uri) { - $gateway = Config::get('cms.updateServer', 'http://gateway.octobercms.com/api'); + $gateway = Config::get('cms.updateServer', 'https://gateway.octobercms.com/api'); if (substr($gateway, -1) != '/') { $gateway .= '/'; } @@ -958,10 +963,10 @@ class UpdateManager */ protected function applyHttpAttributes($http, $postData) { - $postData['protocol_version'] = '1.1'; + $postData['protocol_version'] = '1.2'; $postData['client'] = 'october'; - $postData['server'] = base64_encode(serialize([ + $postData['server'] = base64_encode(json_encode([ 'php' => PHP_VERSION, 'url' => Url::to('/'), 'since' => PluginVersion::orderBy('created_at')->value('created_at') diff --git a/modules/system/classes/VersionManager.php b/modules/system/classes/VersionManager.php index 77127cf12..1cff13a46 100644 --- a/modules/system/classes/VersionManager.php +++ b/modules/system/classes/VersionManager.php @@ -126,6 +126,8 @@ class VersionManager */ protected function applyPluginUpdate($code, $version, $details) { + $version = $this->normalizeVersion($version); + list($comments, $scripts) = $this->extractScriptsAndComments($details); /* @@ -291,13 +293,18 @@ class VersionManager $versionInfo = []; } - if ($versionInfo) { - uksort($versionInfo, function ($a, $b) { - return version_compare($a, $b); - }); + // Sort result + uksort($versionInfo, function ($a, $b) { + return version_compare($a, $b); + }); + + $result = []; + + foreach ($versionInfo as $version => $info) { + $result[$this->normalizeVersion($version)] = $info; } - return $this->fileVersions[$code] = $versionInfo; + return $this->fileVersions[$code] = $result; } /** @@ -549,6 +556,11 @@ class VersionManager return $this; } + protected function normalizeVersion($version) + { + return ltrim((string) $version, 'v'); + } + /** * @param $details * diff --git a/modules/system/twig/SecurityPolicy.php b/modules/system/twig/SecurityPolicy.php index aacd39ba6..b06601e8f 100644 --- a/modules/system/twig/SecurityPolicy.php +++ b/modules/system/twig/SecurityPolicy.php @@ -18,10 +18,18 @@ final class SecurityPolicy implements SecurityPolicyInterface * @var array List of forbidden methods. */ protected $blockedMethods = [ + // \October\Rain\Extension\ExtendableTrait 'addDynamicMethod', 'addDynamicProperty', + + // \October\Rain\Support\Traits\Emitter 'bindEvent', 'bindEventOnce', + + // Eloquent & Halcyon data modification + 'insert', + 'update', + 'delete', ]; /** diff --git a/plugins/bedard/blogtags/Plugin.php b/plugins/bedard/blogtags/Plugin.php index 7ac9f4420..ce670f77c 100644 --- a/plugins/bedard/blogtags/Plugin.php +++ b/plugins/bedard/blogtags/Plugin.php @@ -65,13 +65,21 @@ class Plugin extends PluginBase // extend the post model PostModel::extend(function($model) { - $model->belongsToMany['tags'] = [ + $model->belongsToMany['tags_ru'] = [ 'Bedard\BlogTags\Models\Tag', 'table' => 'bedard_blogtags_post_tag', - 'order' => 'name' + 'order' => 'name', + 'conditions' => 'bedard_blogtags_tags.locale = "ru"' + ]; + $model->belongsToMany['tags_en'] = [ + 'Bedard\BlogTags\Models\Tag', + 'table' => 'bedard_blogtags_post_tag', + 'order' => 'name', + 'conditions' => 'bedard_blogtags_tags.locale = "en"' ]; }); + // extend the post form PostsController::extendFormFields(function($form, $model, $context) { if (!$model instanceof PostModel) { @@ -79,9 +87,17 @@ class Plugin extends PluginBase } $form->addSecondaryTabFields([ - 'tags' => [ - 'label' => 'bedard.blogtags::lang.form.label', + 'tags_ru' => [ + 'label' => 'Tags ru', 'mode' => 'relation', + 'dependsOn' => 'locale', + 'tab' => 'rainlab.blog::lang.post.tab_categories', + 'type' => 'taglist' + ], + 'tags_en' => [ + 'label' => 'Tags en', + 'mode' => 'relation', + 'dependsOn' => 'locale', 'tab' => 'rainlab.blog::lang.post.tab_categories', 'type' => 'taglist' ] diff --git a/plugins/bedard/blogtags/models/Tag.php b/plugins/bedard/blogtags/models/Tag.php index 1fc539daa..944fe0429 100644 --- a/plugins/bedard/blogtags/models/Tag.php +++ b/plugins/bedard/blogtags/models/Tag.php @@ -1,6 +1,7 @@ slug = str_slug($this->name); + $this->locale = input('Post')['locale']; } /** @@ -91,4 +93,6 @@ class Tag extends Model return $this->url = $controller->pageUrl($pageName, $params); } + + } diff --git a/plugins/indikator/devtools/LICENCE.md b/plugins/indikator/devtools/LICENCE.md new file mode 100644 index 000000000..38cee799e --- /dev/null +++ b/plugins/indikator/devtools/LICENCE.md @@ -0,0 +1,19 @@ +# MIT license + +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/plugins/indikator/devtools/Plugin.php b/plugins/indikator/devtools/Plugin.php new file mode 100644 index 000000000..ae2275a7f --- /dev/null +++ b/plugins/indikator/devtools/Plugin.php @@ -0,0 +1,169 @@ + 'indikator.devtools::lang.plugin.name', + 'description' => 'indikator.devtools::lang.plugin.description', + 'author' => 'indikator.devtools::lang.plugin.author', + 'icon' => 'icon-wrench', + 'homepage' => 'https://github.com/gergo85/oc-devtools' + ]; + } + + public function registerSettings() + { + return [ + 'devtool' => [ + 'label' => 'indikator.devtools::lang.help.menu_label', + 'description' => 'indikator.devtools::lang.help.menu_description', + 'icon' => 'icon-wrench', + 'class' => 'Indikator\DevTools\Models\Settings', + 'category' => SettingsManager::CATEGORY_SYSTEM, + 'permissions' => ['indikator.devtools.settings'] + ] + ]; + } + + public function registerFormWidgets() + { + return [ + 'Indikator\DevTools\FormWidgets\Help' => [ + 'label' => 'Help', + 'code' => 'help' + ] + ]; + } + + public function registerPermissions() + { + return [ + 'indikator.devtools.editor' => [ + 'tab' => 'indikator.devtools::lang.plugin.name', + 'label' => 'indikator.devtools::lang.editor.permission', + 'order' => 100, + 'roles' => ['developer'] + ], + 'indikator.devtools.settings' => [ + 'tab' => 'indikator.devtools::lang.plugin.name', + 'label' => 'indikator.devtools::lang.help.permission', + 'order' => 200, + 'roles' => ['developer'] + ] + ]; + } + + public function boot() + { + // Add new menu + BackendMenu::registerCallback(function($manager) { + $manager->registerMenuItems('Indikator.DevTools', [ + 'editor' => [ + 'label' => 'indikator.devtools::lang.editor.menu_label', + 'url' => Backend::url('indikator/devtools/editor'), + 'icon' => 'icon-file-code-o', + 'iconSvg' => 'plugins/indikator/devtools/assets/images/devtools-icon.svg', + 'permissions' => ['indikator.devtools.editor'], + 'order' => 390, + + 'sideMenu' => [ + 'assets' => [ + 'label' => 'indikator.devtools::lang.editor.plugins', + 'icon' => 'icon-cubes', + 'url' => 'javascript:;', + 'attributes' => ['data-menu-item' => 'assets'], + 'counterLabel' => 'cms::lang.asset.unsaved_label', + 'order' => 100 + ] + ] + ] + ]); + }); + + // Add new features + Event::listen('backend.form.extendFields', function($form) + { + // Security check + if (!BackendAuth::check()) { + return; + } + + // Help docs + if ($this->tools_enabled('help') && (get_class($form->config->model) == 'Cms\Classes\Page' || get_class($form->config->model) == 'Cms\Classes\Partial' || get_class($form->config->model) == 'Cms\Classes\Layout') || get_class($form->config->model) == 'Indikator\DevTools\Classes\Asset') { + if (get_class($form->config->model) == 'Indikator\DevTools\Classes\Asset') { + $content = 'php'; + } + else { + $content = 'cms'; + } + + $form->addSecondaryTabFields([ + 'help' => [ + 'label' => '', + 'tab' => 'indikator.devtools::lang.help.tab', + 'type' => 'help', + 'content' => $content + ] + ]); + + return; + } + + // Wysiwyg editor + if ($this->tools_enabled('wysiwyg') && get_class($form->config->model) == 'Cms\Classes\Content') { + foreach ($form->getFields() as $field) { + if (!empty($field->config['type']) && $field->config['type'] == 'codeeditor') { + $field->config['type'] = $field->config['widget'] = 'richeditor'; + } + } + } + }); + } + + public function tools_enabled($name) + { + // Security check + if ($name != 'help' && $name != 'wysiwyg') { + return false; + } + + // Is enabled + if (!Tools::get($name.'_enabled', false)) { + return false; + } + + // My account + $admin = BackendAuth::getUser(); + + // Is superuser + if (Tools::get($name.'_superuser', false) && $admin->is_superuser == 1) { + return true; + } + + // Is admin group + if (Tools::get($name.'_admingroup', false) > 0 && Db::table('backend_users_groups')->where(['user_id' => $admin->id, 'user_group_id' => Tools::get($name.'_admingroup', false)])->count() == 1) { + return true; + } + + // Is current user + if (Tools::get($name.'_adminid', false) > 0 && $admin->id == Tools::get($name.'_adminid', false)) { + return true; + } + + // Finish + return false; + } +} diff --git a/plugins/indikator/devtools/README.md b/plugins/indikator/devtools/README.md new file mode 100644 index 000000000..1e8472938 --- /dev/null +++ b/plugins/indikator/devtools/README.md @@ -0,0 +1,24 @@ +# Developer Tools Plugin +It is a must-have plugin for you, if you use the October's Docs a lot or you want to use the build-in wysiwyg editor on the Content page. + +## Main features +* __Edit directly plugins with the online code editor!__ +* Add a Help tab to the Pages, Partials or Layouts pages. +* Replace the code editor to wysiwyg editor on the Content page. +* Show the PHP's configuration if you logged as Superuser. +* Set a different permissions for the above features. + +## Available languages +* en - English +* hu - Magyar + +## Location of plugin +You can find it in the back-end: __Settings > System > Developer Tools__ + +## PHP's configuration +If you like to get the PHP's configuration of your server, use the following URL: www.yourwebsite.com/phpinfo + +## Installation +1. Go to the __Settings > Updates & Plugins__ page in the Backend. +1. Click on the __Install plugins__ button. +1. Type the __Developer Tools__ text in the search field. diff --git a/plugins/indikator/devtools/assets/images/devtools-icon.svg b/plugins/indikator/devtools/assets/images/devtools-icon.svg new file mode 100644 index 000000000..fe0b1cf34 --- /dev/null +++ b/plugins/indikator/devtools/assets/images/devtools-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/indikator/devtools/assets/october.cmspage.js b/plugins/indikator/devtools/assets/october.cmspage.js new file mode 100644 index 000000000..85cd8e7c6 --- /dev/null +++ b/plugins/indikator/devtools/assets/october.cmspage.js @@ -0,0 +1,706 @@ +/* + * Scripts for the CMS page. + */ ++function ($) { "use strict"; + + var Base = $.oc.foundation.base, + BaseProto = Base.prototype + + var CmsPage = function() { + + Base.call(this) + + // + // Initialization + // + + this.init() + } + + CmsPage.prototype = Object.create(BaseProto) + CmsPage.prototype.constructor = CmsPage + + CmsPage.prototype.init = function() { + $(document).ready(this.proxy(this.registerHandlers)) + } + + CmsPage.prototype.updateTemplateList = function(type) { + var $form = $('#cms-side-panel form[data-template-type='+type+']'), + templateList = type + 'List' + + $form.request(templateList + '::onUpdate', { + complete: function() { + $('button[data-control=delete-template]', $form).trigger('oc.triggerOn.update') + } + }) + } + + CmsPage.prototype.registerHandlers = function() { + var $document = $(document), + $masterTabs = $('#cms-master-tabs') + + $masterTabs.on('closed.oc.tab', this.proxy(this.onTabClosed)) + $masterTabs.on('beforeClose.oc.tab', this.proxy(this.onBeforeTabClose)) + $masterTabs.on('oc.beforeRequest', this.proxy(this.onBeforeRequest)) + $masterTabs.on('shown.bs.tab', this.proxy(this.onTabShown)) + $masterTabs.on('initTab.oc.tab', this.proxy(this.onInitTab)) + $masterTabs.on('afterAllClosed.oc.tab', this.proxy(this.onAfterAllTabsClosed)) + + $(window).on('ajaxInvalidField', this.proxy(this.ajaxInvalidField)) + $document.on('open.oc.list', '#cms-side-panel', this.proxy(this.onOpenDocument)) + $document.on('ajaxUpdate', '[data-control=filelist], [data-control=assetlist]', this.proxy(this.onAjaxUpdate)) + $document.on('ajaxError', '#cms-master-tabs form', this.proxy(this.onAjaxError)) + $document.on('ajaxSuccess', '#cms-master-tabs form', this.proxy(this.onAjaxSuccess)) + $document.on('click', '#cms-side-panel form button[data-control=create-template], #cms-side-panel form li a[data-control=create-template]', this.proxy(this.onCreateTemplateClick)) + $document.on('click', '#cms-side-panel form button[data-control=delete-template]', this.proxy(this.onDeleteTemplateClick)) + $document.on('showing.oc.inspector', '[data-inspectable]', this.proxy(this.onInspectorShowing)) + $document.on('hidden.oc.inspector', '[data-inspectable]', this.proxy(this.onInspectorHidden)) + $document.on('hiding.oc.inspector', '[data-inspectable]', this.proxy(this.onInspectorHiding)) + $document.on('click', '#cms-master-tabs > div.tab-content > .tab-pane.active .control-componentlist a.remove', this.proxy(this.onComponentRemove)) + $document.on('click', '#cms-component-list [data-component]', this.proxy(this.onComponentClick)) + } + + // EVENT HANDLERS + // ============================ + + CmsPage.prototype.onOpenDocument = function(event) { + /* + * Open a document when it's clicked in the sidebar + */ + + var $item = $(event.relatedTarget), + $form = $item.closest('[data-template-type]'), + data = { + type: $form.data('template-type'), + theme: $item.data('item-theme'), + path: $item.data('item-path') + }, + tabId = data.type + '-' + data.theme + '-' + data.path + + if (data.type == 'asset' && $item.data('editable') === undefined) + return true + + if ($form.length == 0) + return false + + /* + * Find if the tab is already opened + */ + if ($('#cms-master-tabs').data('oc.tab').goTo(tabId)) + return false + + /* + * Open a new tab + */ + $.oc.stripeLoadIndicator.show() + + $form.request('onOpenTemplate', { + data: data + }).done(function(data) { + $.oc.stripeLoadIndicator.hide() + var fileType = data.tabTitle.split('.').pop() + if (fileType == 'php' || fileType == 'js' || fileType == 'css' || fileType == 'html' || fileType == 'htm') fileType = 'icon-file-code-o' + else fileType = 'icon-file-text-o' + $('#cms-master-tabs').ocTab('addTab', data.tabTitle, data.tab, tabId, fileType) + }).always(function() { + $.oc.stripeLoadIndicator.hide() + }).fail(function(jqXHR, textStatus, errorThrown) { + alert(jqXHR.responseText.length ? jqXHR.responseText : jqXHR.statusText) + $.oc.stripeLoadIndicator.hide() + }) + + return false + } + + CmsPage.prototype.ajaxInvalidField = function(ev, element, name, messages, isFirst) { + /* + * Detect invalid fields, uncollapse the panel + */ + if (!isFirst) + return + + ev.preventDefault() + + var $el = $(element), + $panel = $el.closest('.form-tabless-fields.collapsed'), + $primaryPanel = $el.closest('.control-tabs.primary-tabs.collapsed') + + if ($panel.length > 0) + $panel.removeClass('collapsed') + + if ($primaryPanel.length > 0) { + $primaryPanel.removeClass('collapsed') + + var pane = $primaryPanel.closest('.tab-pane'), + $secondaryPanel = $('.control-tabs.secondary-tabs', pane) + + $secondaryPanel.removeClass('primary-collapsed') + } + + $el.focus() + } + + CmsPage.prototype.onTabClosed = function(ev) { + this.updateModifiedCounter() + + if ($('> div.tab-content > div.tab-pane', '#cms-master-tabs').length == 0) + this.setPageTitle('') + } + + CmsPage.prototype.onBeforeTabClose = function(ev) { + if ($.fn.table !== undefined) + $('[data-control=table]', ev.relatedTarget).table('dispose') + + $.oc.foundation.controlUtils.disposeControls(ev.relatedTarget.get(0)) + } + + CmsPage.prototype.onBeforeRequest = function(ev) { + var $form = $(ev.target) + + if ($('.components .layout-cell.error-component', $form).length > 0) { + if (!confirm('The form contains unknown components. Their properties will be lost on save. Do you want to save the form?')) + ev.preventDefault() + } + } + + CmsPage.prototype.onTabShown = function(ev) { + /* + * Listen for the tabs "shown" event to track the current template in the list + */ + + var $target = $(ev.target) + + if ($target.closest('[data-control=tab]').attr('id') != 'cms-master-tabs') + return + + var dataId = $target.closest('li').attr('data-tab-id'), + title = $target.attr('title'), + $sidePanel = $('#cms-side-panel') + + if (title) + this.setPageTitle(title) + + $sidePanel.find('[data-control=filelist]').fileList('markActive', dataId) + $sidePanel.find('form').trigger('oc.list.setActiveItem', [dataId]) + } + + CmsPage.prototype.onInitTab = function(ev, data) { + /* + * Listen for the tabs "initTab" event to inject extra controls to the tab + */ + + if ($(ev.target).attr('id') != 'cms-master-tabs') + return + + var $collapseIcon = $(''), + $panel = $('.form-tabless-fields', data.pane) + + $panel.append($collapseIcon); + + $collapseIcon.click(function(){ + $panel.toggleClass('collapsed') + + if (typeof(localStorage) !== 'undefined') + localStorage.ocCmsTablessCollapsed = $panel.hasClass('collapsed') ? 1 : 0 + + window.setTimeout(function(){ + $(window).trigger('oc.updateUi') + }, 500) + + return false + }) + + var $primaryCollapseIcon = $(''), + $primaryPanel = $('.control-tabs.primary-tabs', data.pane), + $secondaryPanel = $('.control-tabs.secondary-tabs', data.pane) + + if ($primaryPanel.length > 0) { + $secondaryPanel.append($primaryCollapseIcon); + + $primaryCollapseIcon.click(function(){ + $primaryPanel.toggleClass('collapsed') + $secondaryPanel.toggleClass('primary-collapsed') + $(window).trigger('oc.updateUi') + if (typeof(localStorage) !== 'undefined') + localStorage.ocCmsPrimaryCollapsed = $primaryPanel.hasClass('collapsed') ? 1 : 0 + return false + }) + } + + if (typeof(localStorage) !== 'undefined') { + if (!$('a', data.tab).hasClass('new-template') && localStorage.ocCmsTablessCollapsed == 1) + $panel.addClass('collapsed') + + if (localStorage.ocCmsPrimaryCollapsed == 1) { + $primaryPanel.addClass('collapsed') + $secondaryPanel.addClass('primary-collapsed') + } + } + + var $componentListFormGroup = $('.control-componentlist', data.pane).closest('.form-group') + if ($primaryPanel.length > 0) + $primaryPanel.before($componentListFormGroup) + else + $secondaryPanel.parent().before($componentListFormGroup) + + $componentListFormGroup.removeClass() + $componentListFormGroup.addClass('layout-row min-size') + this.updateComponentListClass(data.pane) + this.updateFormEditorMode(data.pane, true) + + var $form = $('form', data.pane), + self = this + + $form.on('changed.oc.changeMonitor', function() { + $panel.trigger('modified.oc.tab') + self.updateModifiedCounter() + }) + + $form.on('unchanged.oc.changeMonitor', function() { + $panel.trigger('unmodified.oc.tab') + self.updateModifiedCounter() + }) + + this.addTokenExpanderToEditor(data.pane, $form) + } + + CmsPage.prototype.onAfterAllTabsClosed = function(ev) { + var $sidePanel = $('#cms-side-panel') + + $sidePanel.find('[data-control=filelist]').fileList('markActive', null) + $sidePanel.find('form').trigger('oc.list.setActiveItem', [null]) + } + + CmsPage.prototype.onAjaxUpdate = function(ev) { + var dataId = $('#cms-master-tabs .nav-tabs li.active').attr('data-tab-id'), + $sidePanel = $('#cms-side-panel') + + $sidePanel.find('[data-control=filelist]').fileList('markActive', dataId) + $sidePanel.find('form').trigger('oc.list.setActiveItem', [dataId]) + } + + CmsPage.prototype.onAjaxSuccess = function(ev, context, data) { + var element = ev.target + + if (data.templatePath !== undefined) { + $('input[name=templatePath]', element).val(data.templatePath) + $('input[name=templateMtime]', element).val(data.templateMtime) + $('[data-control=delete-button]', element).removeClass('hide') + $('[data-control=preview-button]', element).removeClass('hide') + + if (data.pageUrl !== undefined) + $('[data-control=preview-button]', element).attr('href', data.pageUrl) + } + + if (data.tabTitle !== undefined) { + $('#cms-master-tabs').ocTab('updateTitle', $(element).closest('.tab-pane'), data.tabTitle) + this.setPageTitle(data.tabTitle) + } + + var tabId = $('input[name=templateType]', element).val() + '-' + + $('input[name=theme]', element).val() + '-' + + $('input[name=templatePath]', element).val(); + + $('#cms-master-tabs').ocTab('updateIdentifier', $(element).closest('.tab-pane'), tabId) + + var templateType = $('input[name=templateType]', element).val() + if (templateType.length > 0) { + $.oc.cmsPage.updateTemplateList(templateType) + + if (templateType == 'layout') + this.updateLayouts(element) + } + + this.updateFormEditorMode($(element).closest('.tab-pane'), false) + + if (context.handler == 'onSave' && (!data['X_OCTOBER_ERROR_FIELDS'] && !data['X_OCTOBER_ERROR_MESSAGE'])) { + $(element).trigger('unchange.oc.changeMonitor') + } + } + + CmsPage.prototype.onAjaxError = function(ev, context, message, data, jqXHR) { + if (context.handler == 'onSave') { + if (jqXHR.responseText == 'mtime-mismatch') { + ev.preventDefault() + this.handleMtimeMismatch(ev.target) + } + } + } + + CmsPage.prototype.onCreateTemplateClick = function(ev) { + var $form = $(ev.target).closest('[data-template-type]'), + type = $form.data('template-type'), + tabId = type + Math.random(), + self = this + + $.oc.stripeLoadIndicator.show() + + $form.request('onCreateTemplate', { + data: {type: type} + }).done(function(data) { + $('#cms-master-tabs').ocTab('addTab', data.tabTitle, data.tab, tabId, $form.data('type-icon') + ' new-template') + $('#layout-side-panel').trigger('close.oc.sidePanel') + self.setPageTitle(data.tabTitle) + }).always(function(){ + $.oc.stripeLoadIndicator.hide() + }) + } + + CmsPage.prototype.onDeleteTemplateClick = function(ev) { + var $el = $(ev.currentTarget), + $form = $el.closest('form'), + templateType = $form.data('template-type'), + self = this + + if (!confirm($el.data('confirmation'))) + return + + $.oc.stripeLoadIndicator.show() + + $form.request('onDeleteTemplates', { + data: {type: templateType} + }).done(function(data) { + var tabs = $('#cms-master-tabs').data('oc.tab'); + $.each(data.deleted, function(index, path){ + var + tabId = templateType + '-' + data.theme + '-' + path, + tab = tabs.findByIdentifier(tabId) + + $('#cms-master-tabs').ocTab('closeTab', tab, true) + }) + + if (data.error !== undefined && $.type(data.error) === 'string' && data.error.length) + $.oc.flashMsg({text: data.error, 'class': 'error'}) + }).always(function(){ + self.updateTemplateList(templateType) + $.oc.stripeLoadIndicator.hide() + }) + } + + CmsPage.prototype.onInspectorShowing = function(ev, data) { + $(ev.currentTarget).closest('[data-control="toolbar"]').data('oc.dragScroll').goToElement(ev.currentTarget, data.callback) + + ev.stopPropagation() + } + + CmsPage.prototype.onInspectorHidden = function(ev) { + var element = ev.target, + values = $.parseJSON($('[data-inspector-values]', element).val()) + + $('[name="component_aliases[]"]', element).val(values['oc.alias']) + $('span.alias', element).text(values['oc.alias']) + } + + CmsPage.prototype.onInspectorHiding = function(ev, values) { + var element = ev.target, + values = $.parseJSON($('[data-inspector-values]', element).val()), + alias = values['oc.alias'], + $componentList = $('#cms-master-tabs > div.tab-content > .tab-pane.active .control-componentlist .layout'), + $cell = $(ev.target).parent() + + $('div.layout-cell', $componentList).each(function(){ + if ($cell.get(0) == this) + return true + + var $input = $('input[name="component_aliases[]"]', this) + + if ($input.val() == alias) { + ev.preventDefault() + alert('The component alias "'+alias+'" is already used.') + return false + } + }) + } + + CmsPage.prototype.onComponentRemove = function(ev) { + var element = ev.currentTarget + + $(element).trigger('change') + var pane = $(element).closest('.tab-pane'), + component = $(element).closest('div.layout-cell') + + /* + * Remove any {% component %} tags in the editor for this component + */ + var editor = $('[data-control=codeeditor]', pane) + if (editor.length) { + var alias = $('input[name="component_aliases[]"]', component).val(), + codeEditor = editor.codeEditor('getEditorObject') + + codeEditor.replace('', { + needle: "{% component '" + alias + "' %}" + }) + } + + component.remove() + $(window).trigger('oc.updateUi') + + this.updateComponentListClass(pane) + return false + } + + CmsPage.prototype.onComponentClick = function(ev) { + /* + * Determine if a page or layout is open in the master tabs + */ + + var $componentList = $('#cms-master-tabs > div.tab-content > .tab-pane.active .control-componentlist .layout') + if ($componentList.length == 0) { + alert('Components can be added only to pages, partials and layouts.') + return; + } + + var $component = $(ev.currentTarget).clone(), + $iconInput = $component.find('[data-component-icon]'), + $componentContainer = $('.layout-relative', $component), + $configInput = $component.find('[data-inspector-config]'), + $aliasInput = $component.find('[data-component-default-alias]'), + $valuesInput = $component.find('[data-inspector-values]'), + $nameInput = $component.find('[data-component-name]'), + $classInput = $component.find('[data-inspector-class]'), + alias = $aliasInput.val(), + originalAlias = alias, + counter = 2, + existingAliases = [] + + $('div.layout-cell input[name="component_aliases[]"]', $componentList).each(function(){ + existingAliases.push($(this).val()) + }) + + while($.inArray(alias, existingAliases) !== -1) { + alias = originalAlias + counter + counter++ + } + + // Set the last alias used so dragComponents can use it + $('input[name="component_aliases[]"]', $(ev.currentTarget)).val(alias) + + $component.attr('data-component-attached', true) + $componentContainer.addClass($iconInput.val()) + $iconInput.remove() + + $componentContainer.attr({ + 'data-inspectable': '', + 'data-inspector-title': $component.find('span.name').text(), + 'data-inspector-description': $component.find('span.description').text(), + 'data-inspector-config': $configInput.val(), + 'data-inspector-class': $classInput.val() + }) + + $configInput.remove() + $('input[name="component_names[]"]', $component).val($nameInput.val()) + $nameInput.remove() + $('input[name="component_aliases[]"]', $component).val(alias) + $component.find('span.alias').text(alias) + $valuesInput.val($valuesInput.val().replace('--alias--', alias)) + $aliasInput.remove() + + $component.addClass('adding') + $componentList.append($component) + $componentList.closest('[data-control="toolbar"]').data('oc.dragScroll').goToElement($component) + $component.removeClass('adding') + $component.trigger('change') + + this.updateComponentListClass($component.closest('.tab-pane')) + + $(window).trigger('oc.updateUi') + } + + // INTERNAL METHODS + // ============================ + + CmsPage.prototype.updateComponentListClass = function(pane) { + var $componentList = $('.control-componentlist', pane), + $primaryPanel = $('.control-tabs.primary-tabs', pane), + $primaryTabContainer = $('.nav-tabs', $primaryPanel), + hasComponents = $('.layout', $componentList).children(':not(.hidden)').length > 0 + + $primaryTabContainer.toggleClass('component-area', hasComponents) + $componentList.toggleClass('has-components', hasComponents) + } + + CmsPage.prototype.updateFormEditorMode = function(pane, initialization) { + var $contentTypeElement = $('[data-toolbar-type]', pane) + if ($contentTypeElement.length == 0) + return + + if ($contentTypeElement.data('toolbar-type') != 'content') + return + + var fileName = $('input[name=fileName]', pane).val(), + parts = fileName.split('.'), + extension = 'txt', + mode = 'plain_text', + modes = { css: "css", htm: "html", html: "html", js: "javascript", less: "less", md: "markdown", sass: "sass", scss: "scss", txt: "plain_text", yaml: "yaml", php: "php" }, + editor = $('[data-control=codeeditor]', pane) + + if (parts.length >= 2) + extension = parts.pop().toLowerCase() + + if (modes[extension] !== undefined) + mode = modes[extension]; + + var setEditorMode = function() { + window.setTimeout(function(){ + editor.data('oc.codeEditor').editor.getSession().setMode({path: 'ace/mode/'+mode}) + }, 200) + } + + if (initialization) + editor.on('oc.codeEditorReady', setEditorMode) + else + setEditorMode() + } + + CmsPage.prototype.updateModifiedCounter = function() { + var counters = { + page: { menu: 'pages', count: 0 }, + partial: { menu: 'partials', count: 0 }, + layout: { menu: 'layouts', count: 0 }, + content: { menu: 'content', count: 0 }, + asset: { menu: 'assets', count: 0} + } + + $('> div.tab-content > div.tab-pane[data-modified]', '#cms-master-tabs').each(function(){ + var inputType = $('> form > input[name=templateType]', this).val() + counters[inputType].count++ + }) + + $.each(counters, function(type, data){ + $.oc.sideNav.setCounter('cms/' + data.menu, data.count); + }) + } + + CmsPage.prototype.addTokenExpanderToEditor = function(pane, $form) { + var group = $('[data-field-name=markup]', pane), + editor = $('[data-control=codeeditor]', group), + canExpand = false, + self = this + + if (!editor.length || editor.data('oc.tokenexpander')) + return + + var toolbar = editor.codeEditor('getToolbar') + + editor.tokenExpander() + + var breakButton = $('
  • ').prop({ 'class': 'tokenexpander-button' }).append( + $('').prop({ 'href': 'javascript:; '}).append( + $('').prop({ 'class': 'icon-code-fork' }) + ) + ) + + breakButton.hide().on('click', function(){ + self.handleExpandToken(editor, $form) + return false + }) + + $('ul:first', toolbar).prepend(breakButton) + + editor + .on('show.oc.tokenexpander', function(){ + canExpand = true + breakButton.show() + }) + .on('hide.oc.tokenexpander', function(){ + canExpand = false + breakButton.hide() + }) + .on('dblclick', function(ev){ + if ((ev.metaKey || ev.ctrlKey) && canExpand) { + self.handleExpandToken(editor, $form) + } + }) + } + + CmsPage.prototype.handleExpandToken = function(editor, $form) { + editor.tokenExpander('expandToken', function(token, value){ + return $form.request('onExpandMarkupToken', { + data: { tokenType: token, tokenName: value } + }) + }) + } + + CmsPage.prototype.handleMtimeMismatch = function(form) { + var $form = $(form) + $form.popup({ handler: 'onOpenConcurrencyResolveForm' }) + + var popup = $form.data('oc.popup'), + self = this + + $(popup.$content).on('click', 'button[data-action=reload]', function(){ + popup.hide() + self.reloadForm(form) + }) + + $(popup.$content).on('click', 'button[data-action=save]', function(){ + popup.hide() + + $('input[name=templateForceSave]', $form).val(1) + $('a[data-request=onSave]', $form).trigger('click') + $('input[name=templateForceSave]', $form).val(0) + }) + } + + CmsPage.prototype.reloadForm = function(form) { + var + $form = $(form), + data = { + type: $('[name=templateType]', $form).val(), + theme: $('[name=theme]', $form).val(), + path: $('[name=templatePath]', $form).val(), + }, + tabId = data.type + '-' + data.theme + '-' + data.path, + tabs = $('#cms-master-tabs').data('oc.tab'), + tab = tabs.findByIdentifier(tabId), + self = this + + /* + * Update tab + */ + + $.oc.stripeLoadIndicator.show() + + $form.request('onOpenTemplate', { + data: data + }).done(function(data) { + $('#cms-master-tabs').ocTab('updateTab', tab, data.tabTitle, data.tab) + $('#cms-master-tabs').ocTab('unmodifyTab', tab) + self.updateModifiedCounter() + }).always(function() { + $.oc.stripeLoadIndicator.hide() + }).fail(function(jqXHR, textStatus, errorThrown) { + alert(jqXHR.responseText.length ? jqXHR.responseText : jqXHR.statusText) + }) + } + + CmsPage.prototype.setPageTitle = function(title) { + if (title.length) + $.oc.layout.setPageTitle(title + ' | ') + else + $.oc.layout.setPageTitle(title) + } + + CmsPage.prototype.updateLayouts = function(form) { + $(form).request('onGetTemplateList', { + success: function(data) { + $('#cms-master-tabs > .tab-content select[name="settings[layout]"]').each(function(){ + var + $select = $(this), + value = $select.val() + + $select.find('option').remove() + $.each(data.layouts, function(layoutFile, layoutName){ + $select.append($('
    + + + + + + + + + + +
    diff --git a/plugins/indikator/devtools/controllers/editor/_form_page.htm b/plugins/indikator/devtools/controllers/editor/_form_page.htm new file mode 100644 index 000000000..918a0ae3b --- /dev/null +++ b/plugins/indikator/devtools/controllers/editor/_form_page.htm @@ -0,0 +1,15 @@ + 'layout', + 'data-change-monitor' => 'true', + 'data-window-close-confirm' => e(trans('backend::lang.form.confirm_tab_close')), + 'data-inspector-external-parameters' => true + ]) ?> + render() ?> + + + + + + + + diff --git a/plugins/indikator/devtools/controllers/editor/_sidepanel.htm b/plugins/indikator/devtools/controllers/editor/_sidepanel.htm new file mode 100644 index 000000000..eb4f705b9 --- /dev/null +++ b/plugins/indikator/devtools/controllers/editor/_sidepanel.htm @@ -0,0 +1,14 @@ +
    +
    +
    +
    + widget->assetList->render() ?> +
    +
    +
    +
    diff --git a/plugins/indikator/devtools/controllers/editor/index.htm b/plugins/indikator/devtools/controllers/editor/index.htm new file mode 100644 index 000000000..dd35315f5 --- /dev/null +++ b/plugins/indikator/devtools/controllers/editor/index.htm @@ -0,0 +1,30 @@ + + fatalError): ?> + makePartial('sidepanel') ?> + + + + + fatalError): ?> +
    + +
    +
    + +
    +
    + +
    +
    + +

    fatalError)) ?>

    + + diff --git a/plugins/indikator/devtools/formwidgets/Help.php b/plugins/indikator/devtools/formwidgets/Help.php new file mode 100644 index 000000000..ddf69a63f --- /dev/null +++ b/plugins/indikator/devtools/formwidgets/Help.php @@ -0,0 +1,30 @@ +fillFromConfig([ + 'content' + ]); + } + + public function render() + { + $this->prepareVars(); + + return $this->makePartial('help'); + } + + protected function prepareVars() + { + $this->vars['content'] = $this->content; + } +} diff --git a/plugins/indikator/devtools/formwidgets/help/partials/_help.htm b/plugins/indikator/devtools/formwidgets/help/partials/_help.htm new file mode 100644 index 000000000..39b2c4796 --- /dev/null +++ b/plugins/indikator/devtools/formwidgets/help/partials/_help.htm @@ -0,0 +1,88 @@ + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + diff --git a/plugins/indikator/devtools/lang/en/lang.php b/plugins/indikator/devtools/lang/en/lang.php new file mode 100644 index 000000000..5c166667b --- /dev/null +++ b/plugins/indikator/devtools/lang/en/lang.php @@ -0,0 +1,72 @@ + [ + 'name' => 'Developer Tools', + 'description' => 'Useful features for developers.', + 'author' => 'Gergő Szabó' + ], + 'editor' => [ + 'menu_label' => 'Code editor', + 'plugins' => 'Plugins', + 'permission' => 'Use the code editor' + ], + 'help' => [ + 'menu_label' => 'Developer Tools', + 'menu_description' => 'Settings of developer features.', + 'tab' => 'Help', + 'cms' => 'CMS', + 'pages' => 'Pages', + 'partials' => 'Partials', + 'layouts' => 'Layouts', + 'content' => 'Content', + 'ajax' => 'AJAX', + 'functions' => 'Functions', + 'tags' => 'Tags', + 'filters' => 'Filters', + 'database' => 'Database', + 'basic' => 'Basic', + 'queries' => 'Queries', + 'plugins' => 'Plugins', + 'registration' => 'Registration', + 'version_history' => 'Version history', + 'building_components' => 'Building components', + 'settings_config' => 'Settings & Config', + 'localization' => 'Localization', + 'task_scheduling' => 'Task scheduling', + 'extending_plugins' => 'Extending plugins', + 'backend' => 'Backend', + 'controllers_ajax' => 'Controllers & AJAX', + 'views_partials' => 'Views & Partials', + 'widgets' => 'Widgets', + 'forms' => 'Forms', + 'lists' => 'Lists', + 'relations' => 'Relations', + 'sorting_records' => 'Sorting records', + 'importing_exporting' => 'Importing & Exporting', + 'users_permissions' => 'Users & Permissions', + 'user_interface_guide' => 'User interface guide', + 'services' => 'Services', + 'application' => 'Application', + 'behaviors' => 'Behaviors', + 'events' => 'Events', + 'forms_html' => 'Forms & Html', + 'mail' => 'Mail', + 'request_input' => 'Request & Input', + 'response_view' => 'Response & View', + 'router' => 'Router', + 'session' => 'Session', + 'validation' => 'Validation', + 'permission' => 'Manage settings' + ], + 'form' => [ + 'wysiwyg_label' => 'Wysiwyg Editor', + 'wysiwyg_enabled' => 'Enabled on the Content page', + 'help_label' => 'Help', + 'help_enabled' => 'Enable the Help tab on the CMS pages', + 'select_none' => '-- None --', + 'select_superuser' => 'Show it for the Superusers', + 'select_admingroup' => 'Show it for the following admin group', + 'select_adminid' => 'Show it for the following administrator', + ] +]; diff --git a/plugins/indikator/devtools/lang/hu/lang.php b/plugins/indikator/devtools/lang/hu/lang.php new file mode 100644 index 000000000..1619fc608 --- /dev/null +++ b/plugins/indikator/devtools/lang/hu/lang.php @@ -0,0 +1,72 @@ + [ + 'name' => 'Fejlesztői eszközök', + 'description' => 'Hasznos szolgáltatások fejlesztőknek.', + 'author' => 'Szabó Gergő' + ], + 'editor' => [ + 'menu_label' => 'Kódszerkesztő', + 'plugins' => 'Bővítmények', + 'permission' => 'Szerkesztő használata' + ], + 'help' => [ + 'menu_label' => 'Fejlesztőknek', + 'menu_description' => 'Szolgáltatások és lehetőségek beállítása.', + 'tab' => 'Súgó', + 'cms' => 'Testreszabás', + 'pages' => 'Lapok', + 'partials' => 'Részlapok', + 'layouts' => 'Elrendezések', + 'content' => 'Tartalom', + 'ajax' => 'AJAX', + 'functions' => 'Függvények', + 'tags' => 'Tag-ek', + 'filters' => 'Filterek', + 'database' => 'Adatbázis', + 'basic' => 'Alapok', + 'queries' => 'Lekérdezések', + 'plugins' => 'Bővítmények', + 'registration' => 'Regisztrálás', + 'version_history' => 'Verzió előzmények', + 'building_components' => 'Komponensek', + 'settings_config' => 'Beállítások', + 'localization' => 'Többnyelvűsítés', + 'task_scheduling' => 'Időzítés', + 'extending_plugins' => 'Kiegészítés', + 'backend' => 'Admin', + 'controllers_ajax' => 'Kontroller és AJAX', + 'views_partials' => 'Részlapok', + 'widgets' => 'Widgetek', + 'forms' => 'Űrlapok', + 'lists' => 'Listák', + 'relations' => 'Kapcsolatok', + 'sorting_records' => 'Elemek rendezése', + 'importing_exporting' => 'Import és export', + 'users_permissions' => 'Jogosultságok', + 'user_interface_guide' => 'Felhasználói felület', + 'services' => 'Szolgáltatások', + 'application' => 'Alkalmazás', + 'behaviors' => 'Viselkedések', + 'events' => 'Események', + 'forms_html' => 'Űrlapok és HTML', + 'mail' => 'Levelezés', + 'request_input' => 'Űrlap értékek', + 'response_view' => 'Válasz megjelenítés', + 'router' => 'Router kezelés', + 'session' => 'Munkamenet', + 'validation' => 'Ellenőrzés', + 'permission' => 'Beállítások kezelése' + ], + 'form' => [ + 'wysiwyg_label' => 'Szövegszerkesztő', + 'wysiwyg_enabled' => 'Engedélyezés a Tartalom oldalon', + 'help_label' => 'Súgó', + 'help_enabled' => 'Engedélyezés a Testreszabás aloldalakon', + 'select_none' => '-- nincs --', + 'select_superuser' => 'Szuperadminok láthatják', + 'select_admingroup' => 'A következő admin csoport tagjai láthatják', + 'select_adminid' => 'A következő admin felhasználó láthatja' + ] +]; diff --git a/plugins/indikator/devtools/models/Settings.php b/plugins/indikator/devtools/models/Settings.php new file mode 100644 index 000000000..879b2a8e2 --- /dev/null +++ b/plugins/indikator/devtools/models/Settings.php @@ -0,0 +1,63 @@ + 'indikator.devtools::lang.form.select_none']; + + public function getHelpAdmingroupOptions() + { + $result = $this->selectList; + $sql = Db::table('backend_user_groups')->orderBy('name', 'asc')->get()->all(); + + foreach ($sql as $item) { + $result[$item->id] = $item->name.' ('.Db::table('backend_users_groups')->where('user_group_id', $item->id)->count().')'; + } + + return $result; + } + + public function getHelpAdminidOptions() + { + $result = $this->selectList; + $sql = Db::table('backend_users')->orderBy('login', 'asc')->get()->all(); + + foreach ($sql as $item) { + $result[$item->id] = $item->login.' ('.$item->email.')'; + } + + return $result; + } + + public function getWysiwygAdmingroupOptions() + { + $result = $this->selectList; + $sql = Db::table('backend_user_groups')->orderBy('name', 'asc')->get()->all(); + + foreach ($sql as $item) { + $result[$item->id] = $item->name.' ('.Db::table('backend_users_groups')->where('user_group_id', $item->id)->count().')'; + } + + return $result; + } + + public function getWysiwygAdminidOptions() + { + $result = $this->selectList; + $sql = Db::table('backend_users')->orderBy('login', 'asc')->get()->all(); + + foreach ($sql as $item) { + $result[$item->id] = $item->login.' ('.$item->email.')'; + } + + return $result; + } +} diff --git a/plugins/indikator/devtools/models/settings/fields.yaml b/plugins/indikator/devtools/models/settings/fields.yaml new file mode 100644 index 000000000..001c7649c --- /dev/null +++ b/plugins/indikator/devtools/models/settings/fields.yaml @@ -0,0 +1,85 @@ +# =================================== +# Field Definitions +# =================================== + +fields: + + help_title: + label: indikator.devtools::lang.form.help_label + type: section + comment: '' + span: left + + wysiwyg_title: + label: indikator.devtools::lang.form.wysiwyg_label + type: section + comment: '' + span: right + + help_enabled: + label: indikator.devtools::lang.form.help_enabled + type: switch + default: false + span: left + + wysiwyg_enabled: + label: indikator.devtools::lang.form.wysiwyg_enabled + type: switch + default: false + span: right + + help_superuser: + label: indikator.devtools::lang.form.select_superuser + type: switch + default: false + trigger: + action: show + field: help_enabled + condition: checked + span: left + + wysiwyg_superuser: + label: indikator.devtools::lang.form.select_superuser + type: switch + default: false + trigger: + action: show + field: wysiwyg_enabled + condition: checked + span: right + + help_admingroup: + label: indikator.devtools::lang.form.select_admingroup + type: dropdown + trigger: + action: show + field: help_enabled + condition: checked + span: left + + wysiwyg_admingroup: + label: indikator.devtools::lang.form.select_admingroup + type: dropdown + trigger: + action: show + field: wysiwyg_enabled + condition: checked + span: right + + help_adminid: + label: indikator.devtools::lang.form.select_adminid + type: dropdown + trigger: + action: show + field: help_enabled + condition: checked + span: left + + wysiwyg_adminid: + label: indikator.devtools::lang.form.select_adminid + type: dropdown + trigger: + action: show + field: wysiwyg_enabled + condition: checked + span: right diff --git a/plugins/indikator/devtools/routes.php b/plugins/indikator/devtools/routes.php new file mode 100644 index 000000000..5bb4d1196 --- /dev/null +++ b/plugins/indikator/devtools/routes.php @@ -0,0 +1,10 @@ +is_superuser == 1) { + echo phpinfo(); + } +}); diff --git a/plugins/indikator/devtools/updates/version.yaml b/plugins/indikator/devtools/updates/version.yaml new file mode 100644 index 000000000..c720a1fe2 --- /dev/null +++ b/plugins/indikator/devtools/updates/version.yaml @@ -0,0 +1,15 @@ +1.0.0: First version of Developer Tools. +1.1.0: Edit plugins with the code editor. +1.1.1: Translate some English texts. +1.1.2: Fixed the Create file issue. +1.1.3: Added new icon for main navigation. +1.1.4: Show the PHP's configuration. +1.1.5: Minor code improvements and bugfix. +1.1.6: The top menu icon shows again. +1.1.7: Fixed the Create folder issue. +1.1.8: !!! Updated for October 420+. +1.1.9: + - Updated the main navigation icon. + - Added last modified date. +1.2.0: The syntax highlighting works again! +1.2.1: Help links open in a new window. diff --git a/plugins/indikator/devtools/widgets/AssetList.php b/plugins/indikator/devtools/widgets/AssetList.php new file mode 100644 index 000000000..d2115dca7 --- /dev/null +++ b/plugins/indikator/devtools/widgets/AssetList.php @@ -0,0 +1,709 @@ +alias = $alias; + $this->theme = Theme::getEditTheme(); + $this->selectionInputName = 'file'; + $this->assetExtensions = FileDefinitions::get('assetExtensions'); + + parent::__construct($controller, []); + $this->bindToController(); + + $this->checkUploadPostback(); + } + + /** + * @inheritDoc + */ + protected function loadAssets() + { + $this->addCss('/modules/cms/widgets/assetlist/assets/css/assetlist.css'); + $this->addJs('/modules/cms/widgets/assetlist/assets/js/assetlist.js'); + } + + /** + * Renders the widget. + * @return string + */ + public function render() + { + return $this->makePartial('body', [ + 'data' => $this->getData() + ]); + } + + // + // Event handlers + // + + public function onOpenDirectory() + { + $path = Input::get('path'); + if (!$this->validatePath($path)) { + throw new ApplicationException(Lang::get('cms::lang.asset.invalid_path')); + } + + $delay = Input::get('delay'); + if ($delay) { + usleep(1000000 * $delay); + } + + $this->putSession('currentPath', $path); + return [ + '#'.$this->getId('asset-list') => $this->makePartial('items', ['items' => $this->getData()]) + ]; + } + + public function onRefresh() + { + return [ + '#'.$this->getId('asset-list') => $this->makePartial('items', ['items' => $this->getData()]) + ]; + } + + public function onUpdate() + { + $this->extendSelection(); + + return $this->onRefresh(); + } + + public function onDeleteFiles() + { + $fileList = Request::input('file'); + $error = null; + $deleted = []; + + try { + $assetsPath = $this->getAssetsPath(); + + foreach ($fileList as $path => $selected) { + if ($selected) { + if (!$this->validatePath($path)) { + throw new ApplicationException(Lang::get('cms::lang.asset.invalid_path')); + } + + $fullPath = $assetsPath.'/'.$path; + if (File::exists($fullPath)) { + if (!File::isDirectory($fullPath)) { + if (!@File::delete($fullPath)) { + throw new ApplicationException(Lang::get( + 'cms::lang.asset.error_deleting_file', + ['name' => $path] + )); + } + } + else { + $empty = File::isDirectoryEmpty($fullPath); + if ($empty === false) { + throw new ApplicationException(Lang::get( + 'cms::lang.asset.error_deleting_dir_not_empty', + ['name' => $path] + )); + } + + if (!@rmdir($fullPath)) { + throw new ApplicationException(Lang::get( + 'cms::lang.asset.error_deleting_dir', + ['name' => $path] + )); + } + } + + $deleted[] = $path; + $this->removeSelection($path); + } + } + } + } + catch (Exception $ex) { + $error = $ex->getMessage(); + } + + return [ + 'deleted' => $deleted, + 'error' => $error + ]; + } + + public function onLoadRenamePopup() + { + $path = Input::get('renamePath'); + if (!$this->validatePath($path)) { + throw new ApplicationException(Lang::get('cms::lang.asset.invalid_path')); + } + + $this->vars['originalPath'] = $path; + $this->vars['name'] = basename($path); + + return $this->makePartial('rename_form'); + } + + public function onApplyName() + { + $newName = trim(Input::get('name')); + if (!strlen($newName)) { + throw new ApplicationException(Lang::get('cms::lang.asset.name_cant_be_empty')); + } + + if (!$this->validatePath($newName)) { + throw new ApplicationException(Lang::get('cms::lang.asset.invalid_path')); + } + + if (!$this->validateName($newName)) { + throw new ApplicationException(Lang::get('cms::lang.asset.invalid_name')); + } + + $originalPath = Input::get('originalPath'); + if (!$this->validatePath($originalPath)) { + throw new ApplicationException(Lang::get('cms::lang.asset.invalid_path')); + } + + $originalFullPath = $this->getFullPath($originalPath); + if (!file_exists($originalFullPath)) { + throw new ApplicationException(Lang::get('cms::lang.asset.original_not_found')); + } + + if (!is_dir($originalFullPath) && !$this->validateFileType($newName)) { + throw new ApplicationException(Lang::get( + 'cms::lang.asset.type_not_allowed', + ['allowed_types' => implode(', ', $this->assetExtensions)] + )); + } + + $newFullPath = $this->getFullPath(dirname($originalPath).'/'.$newName); + if (file_exists($newFullPath) && $newFullPath !== $originalFullPath) { + throw new ApplicationException(Lang::get('cms::lang.asset.already_exists')); + } + + if (!@rename($originalFullPath, $newFullPath)) { + throw new ApplicationException(Lang::get('cms::lang.asset.error_renaming')); + } + + return [ + '#'.$this->getId('asset-list') => $this->makePartial('items', ['items' => $this->getData()]) + ]; + } + + public function onLoadNewDirPopup() + { + return $this->makePartial('new_dir_form'); + } + + public function onNewDirectory() + { + $newName = trim(Input::get('name')); + if (!strlen($newName)) { + throw new ApplicationException(Lang::get('cms::lang.asset.name_cant_be_empty')); + } + + if (!$this->validatePath($newName)) { + throw new ApplicationException(Lang::get('cms::lang.asset.invalid_path')); + } + + if (!$this->validateName($newName)) { + throw new ApplicationException(Lang::get('cms::lang.asset.invalid_name')); + } + + $newFullPath = $this->getCurrentPath().'/'.$newName; + if (file_exists($newFullPath)) { + throw new ApplicationException(Lang::get('cms::lang.asset.already_exists')); + } + + if (!File::makeDirectory($newFullPath)) { + throw new ApplicationException(Lang::get( + 'cms::lang.cms_object.error_creating_directory', + ['name' => $newName] + )); + } + + return [ + '#'.$this->getId('asset-list') => $this->makePartial('items', ['items' => $this->getData()]) + ]; + } + + public function onLoadMovePopup() + { + $fileList = Request::input('file'); + $directories = []; + + $selectedList = array_filter($fileList, function ($value) { + return $value == 1; + }); + + $this->listDestinationDirectories($directories, $selectedList); + + $this->vars['directories'] = $directories; + $this->vars['selectedList'] = base64_encode(json_encode(array_keys($selectedList))); + + return $this->makePartial('move_form'); + } + + public function onMove() + { + $selectedList = Input::get('selectedList'); + if (!strlen($selectedList)) { + throw new ApplicationException(Lang::get('cms::lang.asset.selected_files_not_found')); + } + + $destinationDir = Input::get('dest'); + if (!strlen($destinationDir)) { + throw new ApplicationException(Lang::get('cms::lang.asset.select_destination_dir')); + } + + $destinationFullPath = $this->getFullPath($destinationDir); + if (!file_exists($destinationFullPath) || !is_dir($destinationFullPath)) { + throw new ApplicationException(Lang::get('cms::lang.asset.destination_not_found')); + } + + $list = @json_decode(@base64_decode($selectedList)); + if ($list === false) { + throw new ApplicationException(Lang::get('cms::lang.asset.selected_files_not_found')); + } + + foreach ($list as $path) { + if (!$this->validatePath($path)) { + throw new ApplicationException(Lang::get('cms::lang.asset.invalid_path')); + } + + $basename = basename($path); + $originalFullPath = $this->getFullPath($path); + $newFullPath = rtrim($destinationFullPath, '/').'/'.$basename; + $safeDir = $this->getAssetsPath(); + + if ($originalFullPath == $newFullPath) { + continue; + } + + if (is_file($originalFullPath)) { + if (!@File::move($originalFullPath, $newFullPath)) { + throw new ApplicationException(Lang::get( + 'cms::lang.asset.error_moving_file', + ['file' => $basename] + )); + } + } + elseif (is_dir($originalFullPath)) { + if (!@File::copyDirectory($originalFullPath, $newFullPath)) { + throw new ApplicationException(Lang::get( + 'cms::lang.asset.error_moving_directory', + ['dir' => $basename] + )); + } + + if (strpos($originalFullPath, '../') !== false) { + throw new ApplicationException(Lang::get( + 'cms::lang.asset.error_deleting_directory', + ['dir' => $basename] + )); + } + + if (strpos($originalFullPath, $safeDir) !== 0) { + throw new ApplicationException(Lang::get( + 'cms::lang.asset.error_deleting_directory', + ['dir' => $basename] + )); + } + + if (!@File::deleteDirectory($originalFullPath)) { + throw new ApplicationException(Lang::get( + 'cms::lang.asset.error_deleting_directory', + ['dir' => $basename] + )); + } + } + } + + return [ + '#'.$this->getId('asset-list') => $this->makePartial('items', ['items' => $this->getData()]) + ]; + } + + public function onSearch() + { + $this->setSearchTerm(Input::get('search')); + $this->extendSelection(); + + return $this->onRefresh(); + } + + /* + * Methods for the internal use + */ + + protected function getData() + { + $assetsPath = $this->getAssetsPath(); + + if (!file_exists($assetsPath) || !is_dir($assetsPath)) { + if (!File::makeDirectory($assetsPath)) { + throw new ApplicationException(Lang::get( + 'cms::lang.cms_object.error_creating_directory', + ['name' => $assetsPath] + )); + } + } + + $searchTerm = Str::lower($this->getSearchTerm()); + + if (!strlen($searchTerm)) { + $currentPath = $this->getCurrentPath(); + return $this->getDirectoryContents( + new DirectoryIterator($currentPath) + ); + } + + return $this->findFiles(); + } + + protected function getAssetsPath() + { + return base_path().'/plugins'; + } + + protected function getThemeFileUrl($path) + { + return Url::to('plugins'.$path); + } + + public function getCurrentRelativePath() + { + $path = $this->getSession('currentPath', '/'); + + if (!$this->validatePath($path)) { + return null; + } + + if ($path == '.') { + return null; + } + + return ltrim($path, '/'); + } + + protected function getCurrentPath() + { + $assetsPath = $this->getAssetsPath(); + + $path = $assetsPath.'/'.$this->getCurrentRelativePath(); + if (!is_dir($path)) { + return $assetsPath; + } + + return $path; + } + + protected function getRelativePath($path) + { + $prefix = $this->getAssetsPath(); + + if (substr($path, 0, strlen($prefix)) == $prefix) { + $path = substr($path, strlen($prefix)); + } + + return $path; + } + + protected function getFullPath($path) + { + return $this->getAssetsPath().'/'.ltrim($path, '/'); + } + + protected function validatePath($path) + { + if (!preg_match('/^[0-9a-z\.\s_\-\/]+$/i', $path)) { + return false; + } + + if (strpos($path, '..') !== false || strpos($path, './') !== false) { + return false; + } + + return true; + } + + protected function validateName($name) + { + if (!preg_match('/^[0-9a-z\.\s_\-]+$/i', $name)) { + return false; + } + + if (strpos($name, '..') !== false) { + return false; + } + + return true; + } + + protected function getDirectoryContents($dir) + { + $editableAssetTypes = Asset::getEditableExtensions(); + + $result = $files = []; + + foreach ($dir as $node) { + if (substr($node->getFileName(), 0, 1) == '.') { + continue; + } + + if ($node->isDir() && !$node->isDot()) { + $result[$node->getFilename()] = (object)[ + 'type' => 'directory', + 'path' => File::normalizePath($this->getRelativePath($node->getPathname())), + 'name' => $node->getFilename(), + 'editable' => false + ]; + } + elseif ($node->isFile()) { + $files[] = (object)[ + 'type' => 'file', + 'path' => File::normalizePath($this->getRelativePath($node->getPathname())), + 'name' => $node->getFilename(), + 'editable' => in_array(strtolower($node->getExtension()), $editableAssetTypes) + ]; + } + } + + foreach ($files as $file) { + $result[] = $file; + } + + return $result; + } + + protected function listDestinationDirectories(&$result, $excludeList, $startDir = null, $level = 0) + { + if ($startDir === null) { + $startDir = $this->getAssetsPath(); + + $result['/'] = 'assets'; + $level = 1; + } + + $dirs = new DirectoryIterator($startDir); + foreach ($dirs as $node) { + if (substr($node->getFileName(), 0, 1) == '.') { + continue; + } + + if ($node->isDir() && !$node->isDot()) { + $fullPath = $node->getPathname(); + $relativePath = $this->getRelativePath($fullPath); + if (array_key_exists($relativePath, $excludeList)) { + continue; + } + + $result[$relativePath] = str_repeat(' ', $level * 4).$node->getFilename(); + + $this->listDestinationDirectories($result, $excludeList, $fullPath, $level+1); + } + } + } + + protected function getSearchTerm() + { + return $this->searchTerm !== false ? $this->searchTerm : $this->getSession('search'); + } + + protected function isSearchMode() + { + return strlen($this->getSearchTerm()); + } + + protected function getUpPath() + { + $path = $this->getCurrentRelativePath(); + if (!strlen(rtrim(ltrim($path, '/'), '/'))) { + return null; + } + + return dirname($path); + } + + /** + * Check for valid asset file extension + * @param string + * @return bool + */ + protected function validateFileType($name) + { + $extension = strtolower(File::extension($name)); + + if (!in_array($extension, $this->assetExtensions)) { + return false; + } + + return true; + } + + /** + * Checks the current request to see if it is a postback containing a file upload + * for this particular widget. + */ + protected function checkUploadPostback() + { + $fileName = null; + + try { + $uploadedFile = Input::file('file_data'); + + if (!is_object($uploadedFile)) { + return; + } + + $fileName = $uploadedFile->getClientOriginalName(); + + /* + * Check valid upload + */ + if (!$uploadedFile->isValid()) { + throw new ApplicationException(Lang::get('cms::lang.asset.file_not_valid')); + } + + /* + * Check file size + */ + $maxSize = UploadedFile::getMaxFilesize(); + if ($uploadedFile->getSize() > $maxSize) { + throw new ApplicationException(Lang::get( + 'cms::lang.asset.too_large', + ['max_size' => File::sizeToString($maxSize)] + )); + } + + /* + * Check for valid file extensions + */ + if (!$this->validateFileType($fileName)) { + throw new ApplicationException(Lang::get( + 'cms::lang.asset.type_not_allowed', + ['allowed_types' => implode(', ', $this->assetExtensions)] + )); + } + + /* + * Accept the uploaded file + */ + $uploadedFile->move($this->getCurrentPath(), $uploadedFile->getClientOriginalName()); + + die('success'); + } + catch (Exception $ex) { + $message = $fileName !== null + ? Lang::get('cms::lang.asset.error_uploading_file', ['name' => $fileName, 'error' => $ex->getMessage()]) + : $ex->getMessage(); + + die($message); + } + } + + protected function setSearchTerm($term) + { + $this->searchTerm = trim($term); + $this->putSession('search', $this->searchTerm); + } + + protected function findFiles() + { + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($this->getAssetsPath(), RecursiveDirectoryIterator::SKIP_DOTS), + RecursiveIteratorIterator::SELF_FIRST, + RecursiveIteratorIterator::CATCH_GET_CHILD + ); + + $editableAssetTypes = Asset::getEditableExtensions(); + $searchTerm = Str::lower($this->getSearchTerm()); + $words = explode(' ', $searchTerm); + + $result = []; + foreach ($iterator as $item) { + if (!$item->isDir()) { + if (substr($item->getFileName(), 0, 1) == '.') { + continue; + } + + $path = $this->getRelativePath($item->getPathname()); + + if ($this->pathMatchesSearch($words, $path)) { + $result[] = (object)[ + 'type' => 'file', + 'path' => File::normalizePath($path), + 'name' => $item->getFilename(), + 'editable' => in_array(strtolower($item->getExtension()), $editableAssetTypes) + ]; + } + } + } + + return $result; + } + + protected function pathMatchesSearch(&$words, $path) + { + foreach ($words as $word) { + $word = trim($word); + if (!strlen($word)) { + continue; + } + + if (!Str::contains(Str::lower($path), $word)) { + return false; + } + } + + return true; + } +} diff --git a/plugins/indikator/devtools/widgets/assetlist/partials/_body.htm b/plugins/indikator/devtools/widgets/assetlist/partials/_body.htm new file mode 100644 index 000000000..75dfc389f --- /dev/null +++ b/plugins/indikator/devtools/widgets/assetlist/partials/_body.htm @@ -0,0 +1,8 @@ +makePartial('toolbar') ?> +
    +
    +
    + makePartial('files', ['data'=>$data]) ?> +
    +
    +
    diff --git a/plugins/indikator/devtools/widgets/assetlist/partials/_files.htm b/plugins/indikator/devtools/widgets/assetlist/partials/_files.htm new file mode 100644 index 000000000..8b57fbd6d --- /dev/null +++ b/plugins/indikator/devtools/widgets/assetlist/partials/_files.htm @@ -0,0 +1,7 @@ +
    +
    +
    + makePartial('items', ['items'=>$data]) ?> +
    +
    +
    diff --git a/plugins/indikator/devtools/widgets/assetlist/partials/_items.htm b/plugins/indikator/devtools/widgets/assetlist/partials/_items.htm new file mode 100644 index 000000000..1a378e13c --- /dev/null +++ b/plugins/indikator/devtools/widgets/assetlist/partials/_items.htm @@ -0,0 +1,57 @@ +isSearchMode(); + + if (($upPath = $this->getUpPath()) !== null && !$searchMode): +?> +

    + getCurrentRelativePath() ?> +

    + +
    + +
      + path, '/'); + ?> +
    • editable): ?>data-editable data-item-path="path, '/')) ?>" data-item-type="asset" data-id=""> + + name) ?> + + + + path)) ?> + + + + +
      + +
      + + +
      + path) ?> + isItemSelected($item->path) ? 'checked' : null ?> + data-request="getEventHandler('onSelect') ?>" + value="1"> + +
      + +
    • + +
    + +

    noRecordsMessage)) ?>

    + +
    diff --git a/plugins/indikator/devtools/widgets/assetlist/partials/_move_form.htm b/plugins/indikator/devtools/widgets/assetlist/partials/_move_form.htm new file mode 100644 index 000000000..1cec45953 --- /dev/null +++ b/plugins/indikator/devtools/widgets/assetlist/partials/_move_form.htm @@ -0,0 +1,40 @@ +$this->getEventHandler('onMove'), + 'data-request-success'=>"\$(this).trigger('close.oc.popup')", + 'data-stripe-load-indicator'=>1, + 'id'=>'asset-move-popup-form' +]) ?> + + + + diff --git a/plugins/indikator/devtools/widgets/assetlist/partials/_new_dir_form.htm b/plugins/indikator/devtools/widgets/assetlist/partials/_new_dir_form.htm new file mode 100644 index 000000000..eb5b2ad0c --- /dev/null +++ b/plugins/indikator/devtools/widgets/assetlist/partials/_new_dir_form.htm @@ -0,0 +1,45 @@ +$this->getEventHandler('onNewDirectory'), + 'data-request-success'=>"\$(this).trigger('close.oc.popup')", + 'data-stripe-load-indicator'=>1, + 'id'=>'asset-new-dir-popup-form' +]) ?> + + + + + + + + diff --git a/plugins/indikator/devtools/widgets/assetlist/partials/_rename_form.htm b/plugins/indikator/devtools/widgets/assetlist/partials/_rename_form.htm new file mode 100644 index 000000000..29221a096 --- /dev/null +++ b/plugins/indikator/devtools/widgets/assetlist/partials/_rename_form.htm @@ -0,0 +1,46 @@ +getEventHandler('onApplyName'), [ + 'success' => "\$el.trigger('close.oc.popup');", + 'data-stripe-load-indicator' => 1, + 'id' => 'asset-rename-popup-form' +]) ?> + + + + + + + + diff --git a/plugins/indikator/devtools/widgets/assetlist/partials/_toolbar.htm b/plugins/indikator/devtools/widgets/assetlist/partials/_toolbar.htm new file mode 100644 index 000000000..7764cc0ed --- /dev/null +++ b/plugins/indikator/devtools/widgets/assetlist/partials/_toolbar.htm @@ -0,0 +1,77 @@ +
    +
    + + +
    +
    + + + +
    +
    + + +
    + +
    + +
    +
    diff --git a/plugins/october/demo/Plugin.php b/plugins/october/demo/Plugin.php new file mode 100644 index 000000000..46767095e --- /dev/null +++ b/plugins/october/demo/Plugin.php @@ -0,0 +1,28 @@ + 'October Demo', + 'description' => 'Provides features used by the provided demonstration theme.', + 'author' => 'Alexey Bobkov, Samuel Georges', + 'icon' => 'icon-leaf' + ]; + } + + public function registerComponents() + { + return [ + '\October\Demo\Components\Todo' => 'demoTodo' + ]; + } +} diff --git a/plugins/october/demo/components/Todo.php b/plugins/october/demo/components/Todo.php new file mode 100644 index 000000000..f3cac716e --- /dev/null +++ b/plugins/october/demo/components/Todo.php @@ -0,0 +1,45 @@ + 'Todo List', + 'description' => 'Implements a simple to-do list.' + ]; + } + + public function defineProperties() + { + return [ + 'max' => [ + 'description' => 'The most amount of todo items allowed', + 'title' => 'Max items', + 'default' => 10, + 'type' => 'string', + 'validationPattern' => '^[0-9]+$', + 'validationMessage' => 'The Max Items value is required and should be integer.' + ] + ]; + } + + public function onAddItem() + { + $items = post('items', []); + + if (count($items) >= $this->property('max')) { + throw new ApplicationException(sprintf('Sorry only %s items are allowed.', $this->property('max'))); + } + + if (($newItem = post('newItem')) != '') { + $items[] = $newItem; + } + + $this->page['items'] = $items; + } +} diff --git a/plugins/october/demo/components/todo/default.htm b/plugins/october/demo/components/todo/default.htm new file mode 100644 index 000000000..722b11edf --- /dev/null +++ b/plugins/october/demo/components/todo/default.htm @@ -0,0 +1,22 @@ +
    +
    +
    +

    To Do List

    +
    +
    +
    + + + + +
    +
    +
      +
    +
    +
    diff --git a/plugins/october/demo/components/todo/list.htm b/plugins/october/demo/components/todo/list.htm new file mode 100644 index 000000000..4d2e392f8 --- /dev/null +++ b/plugins/october/demo/components/todo/list.htm @@ -0,0 +1,12 @@ +{% for item in items %} +
  • + + + {{ item }} + + +
  • +{% endfor %} \ No newline at end of file diff --git a/plugins/october/demo/composer.json b/plugins/october/demo/composer.json new file mode 100644 index 000000000..04a07653d --- /dev/null +++ b/plugins/october/demo/composer.json @@ -0,0 +1,34 @@ +{ + "name": "october/demo-plugin", + "type": "october-plugin", + "description": "Demo OctoberCMS plugin", + "keywords": ["october", "cms", "demo", "plugin"], + "license": "MIT", + + "authors": [ + { + "name": "Alexey Bobkov", + "email": "aleksey.bobkov@gmail.com", + "role": "Co-founder" + }, + { + "name": "Samuel Georges", + "email": "daftspunky@gmail.com", + "role": "Co-founder" + } + ], + "require": { + "php": ">=5.4", + "composer/installers": "~1.0" + }, + "autoload": { + "psr-4": { + "October\\Demo\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + } +} \ No newline at end of file diff --git a/plugins/october/demo/updates/version.yaml b/plugins/october/demo/updates/version.yaml new file mode 100644 index 000000000..867bbe886 --- /dev/null +++ b/plugins/october/demo/updates/version.yaml @@ -0,0 +1 @@ +1.0.1: First version of Demo \ No newline at end of file diff --git a/plugins/rainlab/blog/models/Post.php b/plugins/rainlab/blog/models/Post.php index 46436dcff..09b2d8c25 100644 --- a/plugins/rainlab/blog/models/Post.php +++ b/plugins/rainlab/blog/models/Post.php @@ -122,6 +122,16 @@ class Post extends Model */ public function filterFields($fields, $context = null) { + if(isset($fields->locale)){ + if($this->locale == 'en') + { + $fields->tags_en->hidden = false; + $fields->tags_ru->hidden = true; + }else{ + $fields->tags_en->hidden = true; + $fields->tags_ru->hidden = false; + } + } if (!isset($fields->published, $fields->published_at)) { return; } diff --git a/plugins/tps/reklama/Plugin.php b/plugins/tps/reklama/Plugin.php index 2e0cdc91e..d8c2c11fe 100644 --- a/plugins/tps/reklama/Plugin.php +++ b/plugins/tps/reklama/Plugin.php @@ -1,5 +1,6 @@ [ + // A global function, i.e str_plural() + 'media_cdn' => [$this, 'absoluteMediaUrl'], + ], + ]; + } + + public function absoluteMediaUrl($file) { + $original = \System\Classes\MediaLibrary::url($file); + + // modify here and return + return Config::get('cms.cdn').$original; + } } diff --git a/plugins/tps/reklama/components/advertisement/carousel.htm b/plugins/tps/reklama/components/advertisement/carousel.htm index ffe1a7f9e..4679e543b 100644 --- a/plugins/tps/reklama/components/advertisement/carousel.htm +++ b/plugins/tps/reklama/components/advertisement/carousel.htm @@ -13,7 +13,7 @@ data-request-data = '[{id:{{reklama.id}}},{url:"{{reklama.url}}"}]' {% endif %} > - {{reklama.title}} + {{reklama.title}} {% endfor %} diff --git a/plugins/tps/reklama/components/advertisement/single.htm b/plugins/tps/reklama/components/advertisement/single.htm index cac412442..f77685fe1 100644 --- a/plugins/tps/reklama/components/advertisement/single.htm +++ b/plugins/tps/reklama/components/advertisement/single.htm @@ -5,5 +5,5 @@ data-request-data = '[{id:{{reklama.id}}},{url:"{{reklama.url}}"}]' {% endif %} > - {{reklama.title}} + {{reklama.title}} diff --git a/plugins/tps/reklama/components/advertisement/slider.htm b/plugins/tps/reklama/components/advertisement/slider.htm index 80e25ce85..3dd39a182 100644 --- a/plugins/tps/reklama/components/advertisement/slider.htm +++ b/plugins/tps/reklama/components/advertisement/slider.htm @@ -1,12 +1,56 @@ -
    +{% if group and group.adds %} +
    {% for reklama in group.adds %} - - {{reklama.title}} + {{reklama.title}} {% endfor %}
    + + + +{% endif %} diff --git a/storage/framework/classes.php b/storage/framework/classes.php index 846b12c01..4b3c9b040 100644 --- a/storage/framework/classes.php +++ b/storage/framework/classes.php @@ -251,4 +251,6 @@ 'AhmadFatoni\\ApiGenerator\\Controllers\\ApiGeneratorController' => 'plugins/ahmadfatoni/apigenerator/controllers/ApiGeneratorController.php', 'Zen\\Robots\\Controllers\\Generate' => 'plugins/zen/robots/controllers/Generate.php', 'Tps\\Reklama\\Widgets\\Stats' => 'plugins/tps/reklama/widgets/Stats.php', + 'indikator\\devtools\\Plugin' => 'plugins/indikator/devtools/Plugin.php', + 'Indikator\\DevTools\\Models\\Settings' => 'plugins/indikator/devtools/models/Settings.php', ); \ No newline at end of file diff --git a/themes/modern/assets/js/main.js b/themes/modern/assets/js/main.js index fd4d21f57..8812bc2ad 100755 --- a/themes/modern/assets/js/main.js +++ b/themes/modern/assets/js/main.js @@ -121,41 +121,4 @@ if ( ); // lazyload end // ============================================= -// advertisement start -$(function () { - var $slideshow = $(".advertisiment"); - var ImagePauses = [6000, 2000, 3000, 10000]; - // Init - $slideshow.slick({ - dots: false, - arrows: false, - infinite: true, - initialSlide: 0, - autoplay: true, - autoplaySpeed: ImagePauses[0], - fade: true, - cssEase: "linear", - adaptiveHeight: true, - }); - - // Sliding settings - $slideshow.on("afterChange", function (event, slick, currentSlide) { - // Console log, can be removed - console.log( - "Current slide: " + - currentSlide + - ". Setting speed to: " + - ImagePauses[currentSlide] - ); - - // Update autoplay speed according to slide index - $slideshow.slick( - "slickSetOption", - "autoplaySpeed", - ImagePauses[currentSlide], - true - ); - }); -}); -// advertisement end diff --git a/themes/modern/meta/menus/top-menu.yaml b/themes/modern/meta/menus/top-menu.yaml index ec0a1bf62..0aca27ed6 100644 --- a/themes/modern/meta/menus/top-menu.yaml +++ b/themes/modern/meta/menus/top-menu.yaml @@ -1,25 +1,26 @@ items: - title: Главная - nesting: null type: url url: / code: '' - reference: null - cmsPage: null - replace: null viewBag: locale: en: title: Home url: '' - isHidden: '1' + isHidden: '0' cssClass: '' isExternal: '0' - title: Рубрики + nesting: null type: header + url: null code: '' + reference: null + cmsPage: null + replace: null viewBag: locale: en: @@ -31,8 +32,11 @@ items: items: - title: 'New menu item' + nesting: null type: all-blog-categories + url: null code: '' + reference: null cmsPage: category replace: 1 viewBag: diff --git a/themes/modern/pages/index.htm b/themes/modern/pages/index.htm index c9dd93ab1..42d1ae5d0 100644 --- a/themes/modern/pages/index.htm +++ b/themes/modern/pages/index.htm @@ -18,10 +18,20 @@ code = "media" type = "carousel" random = 0 +[adverts adv_bank] +code = "bank" +type = "slider" +random = 0 + [adverts samsung] code = "samsung" type = "single" random = 0 + +[adverts adv_bottom] +code = "bottom" +type = "slider" +random = 0 == {% partial 'slider' %} @@ -31,20 +41,6 @@ random = 0
    diff --git a/themes/modern/partials/index/top_section.htm b/themes/modern/partials/index/top_section.htm index 8ab867d09..35f9e32c8 100644 --- a/themes/modern/partials/index/top_section.htm +++ b/themes/modern/partials/index/top_section.htm @@ -13,7 +13,7 @@
    - + {{firstPost.title}}
    diff --git a/themes/modern/partials/post_list_item.htm b/themes/modern/partials/post_list_item.htm index 65da4b107..2bd5fee16 100644 --- a/themes/modern/partials/post_list_item.htm +++ b/themes/modern/partials/post_list_item.htm @@ -1,8 +1,8 @@
    - + - - + + diff --git a/themes/modern/partials/slider.htm b/themes/modern/partials/slider.htm index 6f2f4cd69..c100a41d4 100644 --- a/themes/modern/partials/slider.htm +++ b/themes/modern/partials/slider.htm @@ -15,7 +15,7 @@ postPage = "post"
    {% for post in posts %}
    - {{post.title}} + {{post.title}} {% if post.categories.count()>0%}
    {{post.categories.implode('name', ', ')}} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 5d573c39a..27a188780 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -6,14 +6,7 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( - 'ArithmeticError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php', - 'AssertionError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php', - 'DivisionByZeroError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php', - 'Error' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/Error.php', 'JSMin' => $vendorDir . '/linkorb/jsmin-php/src/jsmin-1.1.1.php', 'JSMinException' => $vendorDir . '/linkorb/jsmin-php/src/jsmin-1.1.1.php', 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', - 'ParseError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ParseError.php', - 'SessionUpdateTimestampHandlerInterface' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php', - 'TypeError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/TypeError.php', ); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index de9e11451..e6a044809 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -8,9 +8,7 @@ $baseDir = dirname($vendorDir); return array( '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', - '023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', - 'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php', 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index 4e4e3b79a..0da51da14 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -12,6 +12,5 @@ return array( 'Parsedown' => array($vendorDir . '/erusev/parsedown'), 'Less' => array($vendorDir . '/october/rain/src/Parse/Assetic/Less/lib'), 'Doctrine\\DBAL\\' => array($vendorDir . '/doctrine/dbal/lib'), - 'Doctrine\\Common\\Collections\\' => array($vendorDir . '/doctrine/collections/lib'), 'Assetic' => array($vendorDir . '/kriswallsmith/assetic/src'), ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 6b74b3bba..c0e1a6705 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -7,19 +7,17 @@ $baseDir = dirname($vendorDir); return array( 'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'), - 'Wikimedia\\Composer\\' => array($vendorDir . '/wikimedia/composer-merge-plugin/src'), 'Twig\\' => array($vendorDir . '/twig/twig/src'), 'TijsVerkoyen\\CssToInlineStyles\\' => array($vendorDir . '/tijsverkoyen/css-to-inline-styles/src'), 'System\\' => array($baseDir . '/modules/system'), - 'Symfony\\Polyfill\\Util\\' => array($vendorDir . '/symfony/polyfill-util'), 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), - 'Symfony\\Polyfill\\Php70\\' => array($vendorDir . '/symfony/polyfill-php70'), - 'Symfony\\Polyfill\\Php56\\' => array($vendorDir . '/symfony/polyfill-php56'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'), 'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'), 'Symfony\\Polyfill\\Iconv\\' => array($vendorDir . '/symfony/polyfill-iconv'), 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), + 'Symfony\\Contracts\\Translation\\' => array($vendorDir . '/symfony/translation-contracts'), + 'Symfony\\Contracts\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher-contracts'), 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'), 'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'), 'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'), @@ -39,8 +37,8 @@ return array( 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'), 'October\\Rain\\' => array($vendorDir . '/october/rain/src'), - 'October\\Demo\\' => array($baseDir . '/plugins/october/demo'), 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), + 'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'), 'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'), 'League\\Csv\\' => array($vendorDir . '/league/csv/src'), 'Leafo\\ScssPhp\\' => array($vendorDir . '/leafo/scssphp/src'), @@ -51,8 +49,10 @@ return array( 'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'), 'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/src'), 'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'), + 'Doctrine\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector'), 'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer'), 'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Common/Inflector'), + 'Doctrine\\Common\\Collections\\' => array($vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections'), 'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache'), 'Doctrine\\Common\\Annotations\\' => array($vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations'), 'Doctrine\\Common\\' => array($vendorDir . '/doctrine/common/lib/Doctrine/Common'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index a99198466..08daaf4b0 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -9,9 +9,7 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 public static $files = array ( '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', - '023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php', '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', - 'bd9634f2d41831496de0d3dfe4c94881' => __DIR__ . '/..' . '/symfony/polyfill-php56/bootstrap.php', 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php', @@ -32,10 +30,6 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 array ( 'XdgBaseDir\\' => 11, ), - 'W' => - array ( - 'Wikimedia\\Composer\\' => 19, - ), 'T' => array ( 'Twig\\' => 5, @@ -44,15 +38,14 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 'S' => array ( 'System\\' => 7, - 'Symfony\\Polyfill\\Util\\' => 22, 'Symfony\\Polyfill\\Php72\\' => 23, - 'Symfony\\Polyfill\\Php70\\' => 23, - 'Symfony\\Polyfill\\Php56\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, 'Symfony\\Polyfill\\Intl\\Idn\\' => 26, 'Symfony\\Polyfill\\Iconv\\' => 23, 'Symfony\\Polyfill\\Ctype\\' => 23, + 'Symfony\\Contracts\\Translation\\' => 30, + 'Symfony\\Contracts\\EventDispatcher\\' => 34, 'Symfony\\Component\\Yaml\\' => 23, 'Symfony\\Component\\VarDumper\\' => 28, 'Symfony\\Component\\Translation\\' => 30, @@ -81,7 +74,6 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 'O' => array ( 'October\\Rain\\' => 13, - 'October\\Demo\\' => 13, ), 'M' => array ( @@ -89,6 +81,7 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 ), 'L' => array ( + 'League\\MimeTypeDetection\\' => 25, 'League\\Flysystem\\' => 17, 'League\\Csv\\' => 11, 'Leafo\\ScssPhp\\' => 14, @@ -111,8 +104,10 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 'D' => array ( 'Dotenv\\' => 7, + 'Doctrine\\Inflector\\' => 19, 'Doctrine\\Common\\Lexer\\' => 22, 'Doctrine\\Common\\Inflector\\' => 26, + 'Doctrine\\Common\\Collections\\' => 28, 'Doctrine\\Common\\Cache\\' => 22, 'Doctrine\\Common\\Annotations\\' => 28, 'Doctrine\\Common\\' => 16, @@ -134,10 +129,6 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 array ( 0 => __DIR__ . '/..' . '/dnoegel/php-xdg-base-dir/src', ), - 'Wikimedia\\Composer\\' => - array ( - 0 => __DIR__ . '/..' . '/wikimedia/composer-merge-plugin/src', - ), 'Twig\\' => array ( 0 => __DIR__ . '/..' . '/twig/twig/src', @@ -150,22 +141,10 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 array ( 0 => __DIR__ . '/../..' . '/modules/system', ), - 'Symfony\\Polyfill\\Util\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-util', - ), 'Symfony\\Polyfill\\Php72\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php72', ), - 'Symfony\\Polyfill\\Php70\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php70', - ), - 'Symfony\\Polyfill\\Php56\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php56', - ), 'Symfony\\Polyfill\\Mbstring\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', @@ -186,6 +165,14 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', ), + 'Symfony\\Contracts\\Translation\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/translation-contracts', + ), + 'Symfony\\Contracts\\EventDispatcher\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/event-dispatcher-contracts', + ), 'Symfony\\Component\\Yaml\\' => array ( 0 => __DIR__ . '/..' . '/symfony/yaml', @@ -262,14 +249,14 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 array ( 0 => __DIR__ . '/..' . '/october/rain/src', ), - 'October\\Demo\\' => - array ( - 0 => __DIR__ . '/../..' . '/plugins/october/demo', - ), 'Monolog\\' => array ( 0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog', ), + 'League\\MimeTypeDetection\\' => + array ( + 0 => __DIR__ . '/..' . '/league/mime-type-detection/src', + ), 'League\\Flysystem\\' => array ( 0 => __DIR__ . '/..' . '/league/flysystem/src', @@ -310,6 +297,10 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 array ( 0 => __DIR__ . '/..' . '/vlucas/phpdotenv/src', ), + 'Doctrine\\Inflector\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector', + ), 'Doctrine\\Common\\Lexer\\' => array ( 0 => __DIR__ . '/..' . '/doctrine/lexer/lib/Doctrine/Common/Lexer', @@ -318,6 +309,10 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 array ( 0 => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Common/Inflector', ), + 'Doctrine\\Common\\Collections\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/collections/lib/Doctrine/Common/Collections', + ), 'Doctrine\\Common\\Cache\\' => array ( 0 => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache', @@ -391,10 +386,6 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 array ( 0 => __DIR__ . '/..' . '/doctrine/dbal/lib', ), - 'Doctrine\\Common\\Collections\\' => - array ( - 0 => __DIR__ . '/..' . '/doctrine/collections/lib', - ), ), 'A' => array ( @@ -406,16 +397,9 @@ class ComposerStaticInitce290a037d2cbd6fc6b8d537449d0ac2 ); public static $classMap = array ( - 'ArithmeticError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php', - 'AssertionError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php', - 'DivisionByZeroError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php', - 'Error' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/Error.php', 'JSMin' => __DIR__ . '/..' . '/linkorb/jsmin-php/src/jsmin-1.1.1.php', 'JSMinException' => __DIR__ . '/..' . '/linkorb/jsmin-php/src/jsmin-1.1.1.php', 'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', - 'ParseError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ParseError.php', - 'SessionUpdateTimestampHandlerInterface' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php', - 'TypeError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/TypeError.php', ); public static function getInitializer(ClassLoader $loader) diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 0c0c828d3..1f0a1a6ba 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,17 +1,17 @@ [ { "name": "composer/installers", - "version": "v1.9.0", - "version_normalized": "1.9.0.0", + "version": "v1.10.0", + "version_normalized": "1.10.0.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", - "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca" + "reference": "1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca", - "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "url": "https://api.github.com/repos/composer/installers/zipball/1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d", + "reference": "1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d", "shasum": "" }, "require": { @@ -22,18 +22,19 @@ "shama/baton": "*" }, "require-dev": { - "composer/composer": "1.6.* || 2.0.*@dev", - "composer/semver": "1.0.* || 2.0.*@dev", - "phpunit/phpunit": "^4.8.36", - "sebastian/comparator": "^1.2.4", + "composer/composer": "1.6.* || ^2.0", + "composer/semver": "^1 || ^3", + "phpstan/phpstan": "^0.12.55", + "phpstan/phpstan-phpunit": "^0.12.16", + "symfony/phpunit-bridge": "^4.2 || ^5", "symfony/process": "^2.3" }, - "time": "2020-04-07T06:57:05+00:00", + "time": "2021-01-14T11:07:16+00:00", "type": "composer-plugin", "extra": { "class": "Composer\\Installers\\Plugin", "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "1.x-dev" } }, "installation-source": "dist", @@ -72,6 +73,7 @@ "Porto", "RadPHP", "SMF", + "Starbug", "Thelia", "Whmcs", "WolfCMS", @@ -112,6 +114,7 @@ "phpbb", "piwik", "ppi", + "processwire", "puppet", "pxcms", "reindex", @@ -165,34 +168,32 @@ }, { "name": "doctrine/annotations", - "version": "v1.4.0", - "version_normalized": "1.4.0.0", + "version": "1.12.1", + "version_normalized": "1.12.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "54cacc9b81758b14e3ce750f205a393d52339e97" + "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97", - "reference": "54cacc9b81758b14e3ce750f205a393d52339e97", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/b17c5014ef81d212ac539f07a1001832df1b6d3b", + "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b", "shasum": "" }, "require": { "doctrine/lexer": "1.*", - "php": "^5.6 || ^7.0" + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/cache": "1.*", - "phpunit/phpunit": "^5.7" + "doctrine/coding-standard": "^6.0 || ^8.1", + "phpstan/phpstan": "^0.12.20", + "phpunit/phpunit": "^7.5 || ^9.1.5" }, - "time": "2017-02-24T16:22:25+00:00", + "time": "2021-02-21T21:00:45+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, "installation-source": "dist", "autoload": { "psr-4": { @@ -204,6 +205,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -212,10 +217,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -226,7 +227,7 @@ } ], "description": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", "keywords": [ "annotations", "docblock", @@ -235,35 +236,40 @@ }, { "name": "doctrine/cache", - "version": "v1.6.2", - "version_normalized": "1.6.2.0", + "version": "1.10.2", + "version_normalized": "1.10.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b" + "reference": "13e3381b25847283a91948d04640543941309727" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/eb152c5100571c7a45470ff2a35095ab3f3b900b", - "reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b", + "url": "https://api.github.com/repos/doctrine/cache/zipball/13e3381b25847283a91948d04640543941309727", + "reference": "13e3381b25847283a91948d04640543941309727", "shasum": "" }, "require": { - "php": "~5.5|~7.0" + "php": "~7.1 || ^8.0" }, "conflict": { "doctrine/common": ">2.2,<2.4" }, "require-dev": { - "phpunit/phpunit": "~4.8|~5.0", - "predis/predis": "~1.0", - "satooshi/php-coveralls": "~0.6" + "alcaeus/mongo-php-adapter": "^1.1", + "doctrine/coding-standard": "^6.0", + "mongodb/mongodb": "^1.1", + "phpunit/phpunit": "^7.0", + "predis/predis": "~1.0" }, - "time": "2017-07-22T12:49:21+00:00", + "suggest": { + "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" + }, + "time": "2020-07-07T18:54:01+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "1.9.x-dev" } }, "installation-source": "dist", @@ -277,6 +283,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -285,10 +295,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -298,46 +304,50 @@ "email": "schmittjoh@gmail.com" } ], - "description": "Caching library offering an object-oriented API for many cache backends", - "homepage": "http://www.doctrine-project.org", + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", "keywords": [ + "abstraction", + "apcu", "cache", - "caching" + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" ] }, { "name": "doctrine/collections", - "version": "v1.4.0", - "version_normalized": "1.4.0.0", + "version": "1.6.7", + "version_normalized": "1.6.7.0", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba" + "reference": "55f8b799269a1a472457bd1a41b4f379d4cfba4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba", - "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba", + "url": "https://api.github.com/repos/doctrine/collections/zipball/55f8b799269a1a472457bd1a41b4f379d4cfba4a", + "reference": "55f8b799269a1a472457bd1a41b4f379d4cfba4a", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.1.3 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "~0.1@dev", - "phpunit/phpunit": "^5.7" + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan-shim": "^0.9.2", + "phpunit/phpunit": "^7.0", + "vimeo/psalm": "^3.8.1" }, - "time": "2017-01-03T10:49:41+00:00", + "time": "2020-07-27T17:53:49+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, "installation-source": "dist", "autoload": { - "psr-0": { - "Doctrine\\Common\\Collections\\": "lib/" + "psr-4": { + "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" } }, "notification-url": "https://packagist.org/downloads/", @@ -345,6 +355,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -353,10 +367,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -366,12 +376,13 @@ "email": "schmittjoh@gmail.com" } ], - "description": "Collections Abstraction library", - "homepage": "http://www.doctrine-project.org", + "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", + "homepage": "https://www.doctrine-project.org/projects/collections.html", "keywords": [ "array", "collections", - "iterator" + "iterators", + "php" ] }, { @@ -524,36 +535,41 @@ }, { "name": "doctrine/inflector", - "version": "v1.2.0", - "version_normalized": "1.2.0.0", + "version": "1.4.3", + "version_normalized": "1.4.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "e11d84c6e018beedd929cff5220969a3c6d1d462" + "reference": "4650c8b30c753a76bf44fb2ed00117d6f367490c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/e11d84c6e018beedd929cff5220969a3c6d1d462", - "reference": "e11d84c6e018beedd929cff5220969a3c6d1d462", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/4650c8b30c753a76bf44fb2ed00117d6f367490c", + "reference": "4650c8b30c753a76bf44fb2ed00117d6f367490c", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^6.2" + "doctrine/coding-standard": "^7.0", + "phpstan/phpstan": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-strict-rules": "^0.11", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, - "time": "2017-07-22T12:18:28+00:00", + "time": "2020-05-29T07:19:59+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "2.0.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" + "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector", + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" } }, "notification-url": "https://packagist.org/downloads/", @@ -561,6 +577,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -569,10 +589,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -582,41 +598,49 @@ "email": "schmittjoh@gmail.com" } ], - "description": "Common String Manipulations with regard to casing and singular/plural rules.", - "homepage": "http://www.doctrine-project.org", + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", "keywords": [ "inflection", - "pluralize", - "singularize", - "string" + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" ] }, { "name": "doctrine/lexer", - "version": "1.0.2", - "version_normalized": "1.0.2.0", + "version": "1.2.1", + "version_normalized": "1.2.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8" + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/1febd6c3ef84253d7c815bed85fc622ad207a9f8", - "reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^4.5" + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan": "^0.11.8", + "phpunit/phpunit": "^8.2" }, - "time": "2019-06-08T11:03:04+00:00", + "time": "2020-05-25T17:44:05+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "installation-source": "dist", @@ -630,14 +654,14 @@ "MIT" ], "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" @@ -655,37 +679,37 @@ }, { "name": "egulias/email-validator", - "version": "2.1.24", - "version_normalized": "2.1.24.0", + "version": "3.1.1", + "version_normalized": "3.1.1.0", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "ca90a3291eee1538cd48ff25163240695bd95448" + "reference": "c81f18a3efb941d8c4d2e025f6183b5c6d697307" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ca90a3291eee1538cd48ff25163240695bd95448", - "reference": "ca90a3291eee1538cd48ff25163240695bd95448", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/c81f18a3efb941d8c4d2e025f6183b5c6d697307", + "reference": "c81f18a3efb941d8c4d2e025f6183b5c6d697307", "shasum": "" }, "require": { - "doctrine/lexer": "^1.0.1", - "php": ">=5.5", - "symfony/polyfill-intl-idn": "^1.10" + "doctrine/lexer": "^1.2", + "php": ">=7.2", + "symfony/polyfill-intl-idn": "^1.15" }, "require-dev": { - "dominicsayers/isemail": "^3.0.7", - "phpunit/phpunit": "^4.8.36|^7.5.15", - "satooshi/php-coveralls": "^1.0.1" + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^8.5.8|^9.3.3", + "vimeo/psalm": "^4" }, "suggest": { "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" }, - "time": "2020-11-14T15:56:27+00:00", + "time": "2021-04-01T18:37:14+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "3.0.x-dev" } }, "installation-source": "dist", @@ -1416,29 +1440,30 @@ }, { "name": "league/flysystem", - "version": "1.0.70", - "version_normalized": "1.0.70.0", + "version": "1.1.3", + "version_normalized": "1.1.3.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "585824702f534f8d3cf7fab7225e8466cc4b7493" + "reference": "9be3b16c877d477357c015cec057548cf9b2a14a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/585824702f534f8d3cf7fab7225e8466cc4b7493", - "reference": "585824702f534f8d3cf7fab7225e8466cc4b7493", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/9be3b16c877d477357c015cec057548cf9b2a14a", + "reference": "9be3b16c877d477357c015cec057548cf9b2a14a", "shasum": "" }, "require": { "ext-fileinfo": "*", - "php": ">=5.5.9" + "league/mime-type-detection": "^1.3", + "php": "^7.2.5 || ^8.0" }, "conflict": { "league/flysystem-sftp": "<1.0.6" }, "require-dev": { - "phpspec/phpspec": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "phpunit/phpunit": "^5.7.26" + "phpspec/prophecy": "^1.11.1", + "phpunit/phpunit": "^8.5.8" }, "suggest": { "ext-fileinfo": "Required for MimeType", @@ -1456,7 +1481,7 @@ "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" }, - "time": "2020-07-26T07:20:36+00:00", + "time": "2020-08-23T07:39:11+00:00", "type": "library", "extra": { "branch-alias": { @@ -1500,6 +1525,50 @@ "storage" ] }, + { + "name": "league/mime-type-detection", + "version": "1.7.0", + "version_normalized": "1.7.0.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", + "reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.18", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3" + }, + "time": "2021-01-18T20:58:21+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem" + }, { "name": "linkorb/jsmin-php", "version": "1.0.0", @@ -1561,17 +1630,17 @@ }, { "name": "monolog/monolog", - "version": "1.25.5", - "version_normalized": "1.25.5.0", + "version": "1.26.0", + "version_normalized": "1.26.0.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "1817faadd1846cd08be9a49e905dc68823bc38c0" + "reference": "2209ddd84e7ef1256b7af205d0717fb62cfc9c33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1817faadd1846cd08be9a49e905dc68823bc38c0", - "reference": "1817faadd1846cd08be9a49e905dc68823bc38c0", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/2209ddd84e7ef1256b7af205d0717fb62cfc9c33", + "reference": "2209ddd84e7ef1256b7af205d0717fb62cfc9c33", "shasum": "" }, "require": { @@ -1587,7 +1656,7 @@ "graylog2/gelf-php": "~1.0", "php-amqplib/php-amqplib": "~2.4", "php-console/php-console": "^3.1.3", - "php-parallel-lint/php-parallel-lint": "^1.0", + "phpstan/phpstan": "^0.12.59", "phpunit/phpunit": "~4.5", "ruflin/elastica": ">=0.90 <3.0", "sentry/sentry": "^0.13", @@ -1606,13 +1675,8 @@ "ruflin/elastica": "Allow sending log messages to an Elastic Search server", "sentry/sentry": "Allow sending log messages to a Sentry server" }, - "time": "2020-07-23T08:35:51+00:00", + "time": "2020-12-14T12:56:38+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, "installation-source": "dist", "autoload": { "psr-4": { @@ -1750,17 +1814,17 @@ }, { "name": "nikic/php-parser", - "version": "v4.10.2", - "version_normalized": "4.10.2.0", + "version": "v4.10.4", + "version_normalized": "4.10.4.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "658f1be311a230e0907f5dfe0213742aff0596de" + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/658f1be311a230e0907f5dfe0213742aff0596de", - "reference": "658f1be311a230e0907f5dfe0213742aff0596de", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", "shasum": "" }, "require": { @@ -1771,7 +1835,7 @@ "ircmaxell/php-yacc": "^0.0.7", "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, - "time": "2020-09-26T10:30:38+00:00", + "time": "2020-12-20T10:01:03+00:00", "bin": [ "bin/php-parse" ], @@ -1804,17 +1868,17 @@ }, { "name": "october/backend", - "version": "v1.0.469", - "version_normalized": "1.0.469.0", + "version": "v1.0.471", + "version_normalized": "1.0.471.0", "source": { "type": "git", "url": "https://github.com/octoberrain/backend.git", - "reference": "29a9d8171fa4299c1e8543e2476805bda93da7e7" + "reference": "8a109293ee4c838d5219c0edd60ca5902c51322a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/octoberrain/backend/zipball/29a9d8171fa4299c1e8543e2476805bda93da7e7", - "reference": "29a9d8171fa4299c1e8543e2476805bda93da7e7", + "url": "https://api.github.com/repos/octoberrain/backend/zipball/8a109293ee4c838d5219c0edd60ca5902c51322a", + "reference": "8a109293ee4c838d5219c0edd60ca5902c51322a", "shasum": "" }, "require": { @@ -1822,7 +1886,7 @@ "october/rain": "~1.0.469", "php": ">=7.0" }, - "time": "2020-09-07T03:05:00+00:00", + "time": "2020-09-11T08:12:28+00:00", "type": "october-module", "extra": { "branch-alias": { @@ -1865,17 +1929,17 @@ }, { "name": "october/cms", - "version": "v1.0.469", - "version_normalized": "1.0.469.0", + "version": "v1.0.471", + "version_normalized": "1.0.471.0", "source": { "type": "git", "url": "https://github.com/octoberrain/cms.git", - "reference": "5fdc7bc3eb3a8122812b00e00f9c6150c35fca1a" + "reference": "da3c2c8a9078774da80a6bce4ddf6bb76bb329f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/octoberrain/cms/zipball/5fdc7bc3eb3a8122812b00e00f9c6150c35fca1a", - "reference": "5fdc7bc3eb3a8122812b00e00f9c6150c35fca1a", + "url": "https://api.github.com/repos/octoberrain/cms/zipball/da3c2c8a9078774da80a6bce4ddf6bb76bb329f4", + "reference": "da3c2c8a9078774da80a6bce4ddf6bb76bb329f4", "shasum": "" }, "require": { @@ -1883,7 +1947,7 @@ "october/rain": "~1.0.469", "php": ">=7.0" }, - "time": "2020-09-07T03:05:00+00:00", + "time": "2020-09-11T21:48:58+00:00", "type": "october-module", "extra": { "branch-alias": { @@ -1926,17 +1990,17 @@ }, { "name": "october/rain", - "version": "v1.0.469", - "version_normalized": "1.0.469.0", + "version": "v1.0.471", + "version_normalized": "1.0.471.0", "source": { "type": "git", "url": "https://github.com/octobercms/library.git", - "reference": "75156886dc53e8f215b4d7455ac098416d98cb84" + "reference": "16d8346e40af5da98b454e7fe1810d702a34667e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/octobercms/library/zipball/75156886dc53e8f215b4d7455ac098416d98cb84", - "reference": "75156886dc53e8f215b4d7455ac098416d98cb84", + "url": "https://api.github.com/repos/octobercms/library/zipball/16d8346e40af5da98b454e7fe1810d702a34667e", + "reference": "16d8346e40af5da98b454e7fe1810d702a34667e", "shasum": "" }, "require": { @@ -1988,7 +2052,7 @@ "symfony/css-selector": "~3.1", "symfony/dom-crawler": "~3.1" }, - "time": "2020-09-04T16:20:04+00:00", + "time": "2020-11-20T09:48:36+00:00", "type": "library", "extra": { "branch-alias": { @@ -2033,17 +2097,17 @@ }, { "name": "october/system", - "version": "v1.0.469", - "version_normalized": "1.0.469.0", + "version": "v1.0.471", + "version_normalized": "1.0.471.0", "source": { "type": "git", "url": "https://github.com/octoberrain/system.git", - "reference": "c4ba5af16f57a6f7db2520b8f62962da23778399" + "reference": "194625e6ae326160d02ec72609e8056c3c11e3c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/octoberrain/system/zipball/c4ba5af16f57a6f7db2520b8f62962da23778399", - "reference": "c4ba5af16f57a6f7db2520b8f62962da23778399", + "url": "https://api.github.com/repos/octoberrain/system/zipball/194625e6ae326160d02ec72609e8056c3c11e3c9", + "reference": "194625e6ae326160d02ec72609e8056c3c11e3c9", "shasum": "" }, "require": { @@ -2051,7 +2115,7 @@ "october/rain": "~1.0.469", "php": ">=7.0" }, - "time": "2020-09-07T03:05:00+00:00", + "time": "2020-11-13T09:50:39+00:00", "type": "october-module", "extra": { "branch-alias": { @@ -2141,29 +2205,24 @@ }, { "name": "psr/container", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "version": "1.1.1", + "version_normalized": "1.1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, - "time": "2017-02-14T16:28:37+00:00", + "time": "2021-03-05T17:36:06+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "installation-source": "dist", "autoload": { "psr-4": { @@ -2177,7 +2236,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -2456,35 +2515,34 @@ }, { "name": "swiftmailer/swiftmailer", - "version": "v6.2.3", - "version_normalized": "6.2.3.0", + "version": "v6.2.7", + "version_normalized": "6.2.7.0", "source": { "type": "git", "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9" + "reference": "15f7faf8508e04471f666633addacf54c0ab5933" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/149cfdf118b169f7840bbe3ef0d4bc795d1780c9", - "reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/15f7faf8508e04471f666633addacf54c0ab5933", + "reference": "15f7faf8508e04471f666633addacf54c0ab5933", "shasum": "" }, "require": { - "egulias/email-validator": "~2.0", + "egulias/email-validator": "^2.0|^3.1", "php": ">=7.0.0", "symfony/polyfill-iconv": "^1.0", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, "require-dev": { - "mockery/mockery": "~0.9.1", - "symfony/phpunit-bridge": "^3.4.19|^4.1.8" + "mockery/mockery": "^1.0", + "symfony/phpunit-bridge": "^4.4|^5.0" }, "suggest": { - "ext-intl": "Needed to support internationalized email addresses", - "true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed" + "ext-intl": "Needed to support internationalized email addresses" }, - "time": "2019-11-12T09:31:26+00:00", + "time": "2021-03-09T12:30:35+00:00", "type": "library", "extra": { "branch-alias": { @@ -2520,8 +2578,8 @@ }, { "name": "symfony/console", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", @@ -2589,23 +2647,23 @@ }, { "name": "symfony/css-selector", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "version": "v5.2.4", + "version_normalized": "5.2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33" + "reference": "f65f217b3314504a1ec99c2d6ef69016bb13490f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/da3d9da2ce0026771f5fe64cb332158f1bd2bc33", - "reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/f65f217b3314504a1ec99c2d6ef69016bb13490f", + "reference": "f65f217b3314504a1ec99c2d6ef69016bb13490f", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=7.2.5" }, - "time": "2020-10-24T10:57:07+00:00", + "time": "2021-01-27T10:01:46+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2634,13 +2692,13 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony CssSelector Component", + "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com" }, { "name": "symfony/debug", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", @@ -2692,38 +2750,45 @@ }, { "name": "symfony/event-dispatcher", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "version": "v4.4.20", + "version_normalized": "4.4.20.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "31fde73757b6bad247c54597beef974919ec6860" + "reference": "c352647244bd376bf7d31efbd5401f13f50dad0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/31fde73757b6bad247c54597beef974919ec6860", - "reference": "31fde73757b6bad247c54597beef974919ec6860", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c352647244bd376bf7d31efbd5401f13f50dad0c", + "reference": "c352647244bd376bf7d31efbd5401f13f50dad0c", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=7.1.3", + "symfony/event-dispatcher-contracts": "^1.1" }, "conflict": { - "symfony/dependency-injection": "<3.3" + "symfony/dependency-injection": "<3.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "1.1" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.8|~3.0|~4.0", - "symfony/debug": "~3.4|~4.4", - "symfony/dependency-injection": "~3.3|~4.0", - "symfony/expression-language": "~2.8|~3.0|~4.0", - "symfony/stopwatch": "~2.8|~3.0|~4.0" + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/error-handler": "~3.4|~4.4", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/stopwatch": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/dependency-injection": "", "symfony/http-kernel": "" }, - "time": "2020-10-24T10:57:07+00:00", + "time": "2021-01-27T09:09:26+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2748,28 +2813,92 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony EventDispatcher Component", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com" }, { - "name": "symfony/finder", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "name": "symfony/event-dispatcher-contracts", + "version": "v1.1.9", + "version_normalized": "1.1.9.0", "source": { "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "4e1da3c110c52d868f8a9153b7de3ebc381fba78" + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/4e1da3c110c52d868f8a9153b7de3ebc381fba78", - "reference": "4e1da3c110c52d868f8a9153b7de3ebc381fba78", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/84e23fdcd2517bf37aecbd16967e83f0caee25a7", + "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7", + "shasum": "" + }, + "require": { + "php": ">=7.1.3" + }, + "suggest": { + "psr/event-dispatcher": "", + "symfony/event-dispatcher-implementation": "" + }, + "time": "2020-07-06T13:19:58+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "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": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ] + }, + { + "name": "symfony/finder", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "b6b6ad3db3edb1b4b1c1896b1975fb684994de6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/b6b6ad3db3edb1b4b1c1896b1975fb684994de6e", + "reference": "b6b6ad3db3edb1b4b1c1896b1975fb684994de6e", "shasum": "" }, "require": { "php": "^5.5.9|>=7.0.8" }, - "time": "2020-10-24T10:57:07+00:00", + "time": "2020-11-16T17:02:08+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2799,8 +2928,8 @@ }, { "name": "symfony/http-foundation", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", @@ -2850,17 +2979,17 @@ }, { "name": "symfony/http-kernel", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "09f8e3f9eb6d1c0e08abb0c9ad7d02f93b1d633d" + "reference": "a98a4c30089e6a2d52a9fa236f718159b539f6f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/09f8e3f9eb6d1c0e08abb0c9ad7d02f93b1d633d", - "reference": "09f8e3f9eb6d1c0e08abb0c9ad7d02f93b1d633d", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a98a4c30089e6a2d52a9fa236f718159b539f6f5", + "reference": "a98a4c30089e6a2d52a9fa236f718159b539f6f5", "shasum": "" }, "require": { @@ -2907,7 +3036,7 @@ "symfony/finder": "", "symfony/var-dumper": "" }, - "time": "2020-10-28T05:40:17+00:00", + "time": "2020-11-27T08:42:42+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2937,30 +3066,30 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.19.0", - "version_normalized": "1.19.0.0", + "version": "v1.22.1", + "version_normalized": "1.22.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b" + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b", - "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-ctype": "For best performance" }, - "time": "2020-10-23T09:01:57+00:00", + "time": "2021-01-07T16:49:33+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3001,30 +3130,30 @@ }, { "name": "symfony/polyfill-iconv", - "version": "v1.19.0", - "version_normalized": "1.19.0.0", + "version": "v1.22.1", + "version_normalized": "1.22.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "085241787d52fa6f7a774fd034135fef0cfd5496" + "reference": "06fb361659649bcfd6a208a0f1fcaf4e827ad342" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/085241787d52fa6f7a774fd034135fef0cfd5496", - "reference": "085241787d52fa6f7a774fd034135fef0cfd5496", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/06fb361659649bcfd6a208a0f1fcaf4e827ad342", + "reference": "06fb361659649bcfd6a208a0f1fcaf4e827ad342", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-iconv": "For best performance" }, - "time": "2020-10-23T09:01:57+00:00", + "time": "2021-01-22T09:19:47+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3066,33 +3195,32 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.19.0", - "version_normalized": "1.19.0.0", + "version": "v1.22.1", + "version_normalized": "1.22.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "4ad5115c0f5d5172a9fe8147675ec6de266d8826" + "reference": "2d63434d922daf7da8dd863e7907e67ee3031483" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/4ad5115c0f5d5172a9fe8147675ec6de266d8826", - "reference": "4ad5115c0f5d5172a9fe8147675ec6de266d8826", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/2d63434d922daf7da8dd863e7907e67ee3031483", + "reference": "2d63434d922daf7da8dd863e7907e67ee3031483", "shasum": "" }, "require": { - "php": ">=5.3.3", + "php": ">=7.1", "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php70": "^1.10", "symfony/polyfill-php72": "^1.10" }, "suggest": { "ext-intl": "For best performance" }, - "time": "2020-10-21T09:57:48+00:00", + "time": "2021-01-22T09:19:47+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3139,30 +3267,30 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.19.0", - "version_normalized": "1.19.0.0", + "version": "v1.22.1", + "version_normalized": "1.22.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8db0ae7936b42feb370840cf24de1a144fb0ef27" + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8db0ae7936b42feb370840cf24de1a144fb0ef27", - "reference": "8db0ae7936b42feb370840cf24de1a144fb0ef27", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" }, - "time": "2020-10-23T09:01:57+00:00", + "time": "2021-01-22T09:19:47+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3208,30 +3336,30 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.19.0", - "version_normalized": "1.19.0.0", + "version": "v1.22.1", + "version_normalized": "1.22.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "b5f7b932ee6fa802fc792eabd77c4c88084517ce" + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b5f7b932ee6fa802fc792eabd77c4c88084517ce", - "reference": "b5f7b932ee6fa802fc792eabd77c4c88084517ce", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-mbstring": "For best performance" }, - "time": "2020-10-23T09:01:57+00:00", + "time": "2021-01-22T09:19:47+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3273,43 +3401,33 @@ }, { "name": "symfony/polyfill-php56", - "version": "v1.19.0", - "version_normalized": "1.19.0.0", + "version": "v1.20.0", + "version_normalized": "1.20.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php56.git", - "reference": "ea19621731cbd973a6702cfedef3419768bf3372" + "reference": "54b8cd7e6c1643d78d011f3be89f3ef1f9f4c675" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/ea19621731cbd973a6702cfedef3419768bf3372", - "reference": "ea19621731cbd973a6702cfedef3419768bf3372", + "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/54b8cd7e6c1643d78d011f3be89f3ef1f9f4c675", + "reference": "54b8cd7e6c1643d78d011f3be89f3ef1f9f4c675", "shasum": "" }, "require": { - "php": ">=5.3.3", - "symfony/polyfill-util": "~1.0" + "php": ">=7.1" }, - "time": "2020-10-23T09:01:57+00:00", - "type": "library", + "time": "2020-10-23T14:02:19+00:00", + "type": "metapackage", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php56\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" @@ -3335,46 +3453,33 @@ }, { "name": "symfony/polyfill-php70", - "version": "v1.19.0", - "version_normalized": "1.19.0.0", + "version": "v1.20.0", + "version_normalized": "1.20.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "3fe414077251a81a1b15b1c709faf5c2fbae3d4e" + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3fe414077251a81a1b15b1c709faf5c2fbae3d4e", - "reference": "3fe414077251a81a1b15b1c709faf5c2fbae3d4e", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", "shasum": "" }, "require": { - "paragonie/random_compat": "~1.0|~2.0|~9.99", - "php": ">=5.3.3" + "php": ">=7.1" }, - "time": "2020-10-23T09:01:57+00:00", - "type": "library", + "time": "2020-10-23T14:02:19+00:00", + "type": "metapackage", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" @@ -3400,27 +3505,27 @@ }, { "name": "symfony/polyfill-php72", - "version": "v1.19.0", - "version_normalized": "1.19.0.0", + "version": "v1.22.1", + "version_normalized": "1.22.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "beecef6b463b06954638f02378f52496cb84bacc" + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/beecef6b463b06954638f02378f52496cb84bacc", - "reference": "beecef6b463b06954638f02378f52496cb84bacc", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, - "time": "2020-10-23T09:01:57+00:00", + "time": "2021-01-07T16:49:33+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3459,68 +3564,10 @@ "shim" ] }, - { - "name": "symfony/polyfill-util", - "version": "v1.19.0", - "version_normalized": "1.19.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-util.git", - "reference": "8df0c3e6a4b85df9a5c6f3f2f46fba5c5c47058a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/8df0c3e6a4b85df9a5c6f3f2f46fba5c5c47058a", - "reference": "8df0c3e6a4b85df9a5c6f3f2f46fba5c5c47058a", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2020-10-21T09:57:48+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.19-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Util\\": "" - } - }, - "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 utilities for portability of PHP codes", - "homepage": "https://symfony.com", - "keywords": [ - "compat", - "compatibility", - "polyfill", - "shim" - ] - }, { "name": "symfony/process", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", @@ -3565,8 +3612,8 @@ }, { "name": "symfony/routing", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", @@ -3638,35 +3685,41 @@ }, { "name": "symfony/translation", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "version": "v4.3.11", + "version_normalized": "4.3.11.0", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "be83ee6c065cb32becdb306ba61160d598b1ce88" + "reference": "46e462be71935ae15eab531e4d491d801857f24c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/be83ee6c065cb32becdb306ba61160d598b1ce88", - "reference": "be83ee6c065cb32becdb306ba61160d598b1ce88", + "url": "https://api.github.com/repos/symfony/translation/zipball/46e462be71935ae15eab531e4d491d801857f24c", + "reference": "46e462be71935ae15eab531e4d491d801857f24c", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/polyfill-mbstring": "~1.0" + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^1.1.6" }, "conflict": { - "symfony/config": "<2.8", + "symfony/config": "<3.4", "symfony/dependency-injection": "<3.4", "symfony/yaml": "<3.4" }, + "provide": { + "symfony/translation-implementation": "1.0" + }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.8|~3.0|~4.0", + "symfony/config": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", "symfony/dependency-injection": "~3.4|~4.0", "symfony/finder": "~2.8|~3.0|~4.0", "symfony/http-kernel": "~3.4|~4.0", - "symfony/intl": "^2.8.18|^3.2.5|~4.0", + "symfony/intl": "~3.4|~4.0", + "symfony/service-contracts": "^1.1.2", "symfony/var-dumper": "~3.4|~4.0", "symfony/yaml": "~3.4|~4.0" }, @@ -3675,8 +3728,13 @@ "symfony/config": "", "symfony/yaml": "" }, - "time": "2020-10-24T10:57:07+00:00", + "time": "2020-01-04T12:24:57+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.3-dev" + } + }, "installation-source": "dist", "autoload": { "psr-4": { @@ -3703,10 +3761,73 @@ "description": "Symfony Translation Component", "homepage": "https://symfony.com" }, + { + "name": "symfony/translation-contracts", + "version": "v1.1.10", + "version_normalized": "1.1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "84180a25fad31e23bebd26ca09d89464f082cacc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/84180a25fad31e23bebd26ca09d89464f082cacc", + "reference": "84180a25fad31e23bebd26ca09d89464f082cacc", + "shasum": "" + }, + "require": { + "php": ">=7.1.3" + }, + "suggest": { + "symfony/translation-implementation": "" + }, + "time": "2020-09-02T16:08:58+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + } + }, + "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": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ] + }, { "name": "symfony/var-dumper", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", @@ -3771,8 +3892,8 @@ }, { "name": "symfony/yaml", - "version": "v3.4.46", - "version_normalized": "3.4.46.0", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", @@ -3878,33 +3999,33 @@ }, { "name": "twig/twig", - "version": "v2.12.5", - "version_normalized": "2.12.5.0", + "version": "v2.14.4", + "version_normalized": "2.14.4.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "18772e0190734944277ee97a02a9a6c6555fcd94" + "reference": "0b4ba691fb99ec7952d25deb36c0a83061b93bbf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/18772e0190734944277ee97a02a9a6c6555fcd94", - "reference": "18772e0190734944277ee97a02a9a6c6555fcd94", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/0b4ba691fb99ec7952d25deb36c0a83061b93bbf", + "reference": "0b4ba691fb99ec7952d25deb36c0a83061b93bbf", "shasum": "" }, "require": { - "php": "^7.0", + "php": ">=7.2.5", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4|^5.0" + "symfony/phpunit-bridge": "^4.4.9|^5.0.9" }, - "time": "2020-02-11T15:31:23+00:00", + "time": "2021-03-10T10:05:55+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.12-dev" + "dev-master": "2.14-dev" } }, "installation-source": "dist", @@ -3945,17 +4066,17 @@ }, { "name": "vlucas/phpdotenv", - "version": "v2.6.6", - "version_normalized": "2.6.6.0", + "version": "v2.6.7", + "version_normalized": "2.6.7.0", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "e1d57f62db3db00d9139078cbedf262280701479" + "reference": "b786088918a884258c9e3e27405c6a4cf2ee246e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/e1d57f62db3db00d9139078cbedf262280701479", - "reference": "e1d57f62db3db00d9139078cbedf262280701479", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/b786088918a884258c9e3e27405c6a4cf2ee246e", + "reference": "b786088918a884258c9e3e27405c6a4cf2ee246e", "shasum": "" }, "require": { @@ -3965,13 +4086,13 @@ "require-dev": { "ext-filter": "*", "ext-pcre": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7.27" + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20" }, "suggest": { "ext-filter": "Required to use the boolean validator.", "ext-pcre": "Required to use most of the library." }, - "time": "2020-07-14T17:54:18+00:00", + "time": "2021-01-20T14:39:13+00:00", "type": "library", "extra": { "branch-alias": { @@ -4006,56 +4127,5 @@ "env", "environment" ] - }, - { - "name": "wikimedia/composer-merge-plugin", - "version": "v1.4.1", - "version_normalized": "1.4.1.0", - "source": { - "type": "git", - "url": "https://github.com/wikimedia/composer-merge-plugin.git", - "reference": "81c6ac72a24a67383419c7eb9aa2b3437f2ab100" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/81c6ac72a24a67383419c7eb9aa2b3437f2ab100", - "reference": "81c6ac72a24a67383419c7eb9aa2b3437f2ab100", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0", - "php": ">=5.3.2" - }, - "require-dev": { - "composer/composer": "~1.0.0", - "jakub-onderka/php-parallel-lint": "~0.8", - "phpunit/phpunit": "~4.8|~5.0", - "squizlabs/php_codesniffer": "~2.1.0" - }, - "time": "2017-04-25T02:31:25+00:00", - "type": "composer-plugin", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - }, - "class": "Wikimedia\\Composer\\MergePlugin" - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Wikimedia\\Composer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bryan Davis", - "email": "bd808@wikimedia.org" - } - ], - "description": "Composer plugin to merge multiple composer.json files" } ] diff --git a/vendor/composer/installers/composer.json b/vendor/composer/installers/composer.json index c21715da3..61c0b7f45 100644 --- a/vendor/composer/installers/composer.json +++ b/vendor/composer/installers/composer.json @@ -57,12 +57,14 @@ "PPI", "Puppet", "Porto", + "ProcessWire", "RadPHP", "ReIndex", "Roundcube", "shopware", "SilverStripe", "SMF", + "Starbug", "SyDES", "Sylius", "symfony", @@ -86,10 +88,13 @@ "autoload": { "psr-4": { "Composer\\Installers\\": "src/Composer/Installers" } }, + "autoload-dev": { + "psr-4": { "Composer\\Installers\\Test\\": "tests/Composer/Installers/Test" } + }, "extra": { "class": "Composer\\Installers\\Plugin", "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "1.x-dev" } }, "replace": { @@ -100,13 +105,15 @@ "composer-plugin-api": "^1.0 || ^2.0" }, "require-dev": { - "composer/composer": "1.6.* || 2.0.*@dev", - "composer/semver": "1.0.* || 2.0.*@dev", - "phpunit/phpunit": "^4.8.36", - "sebastian/comparator": "^1.2.4", - "symfony/process": "^2.3" + "composer/composer": "1.6.* || ^2.0", + "composer/semver": "^1 || ^3", + "symfony/phpunit-bridge": "^4.2 || ^5", + "phpstan/phpstan": "^0.12.55", + "symfony/process": "^2.3", + "phpstan/phpstan-phpunit": "^0.12.16" }, "scripts": { - "test": "phpunit" + "test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit", + "phpstan": "vendor/bin/phpstan analyse" } } diff --git a/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php b/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php index d9d607355..70dde907e 100644 --- a/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php @@ -74,8 +74,8 @@ abstract class BaseInstaller /** * For an installer to override to modify the vars per installer. * - * @param array $vars - * @return array + * @param array $vars This will normally receive array{name: string, vendor: string, type: string} + * @return array */ public function inflectPackageVars($vars) { @@ -85,7 +85,7 @@ abstract class BaseInstaller /** * Gets the installer's locations * - * @return array + * @return array map of package types => install path */ public function getLocations() { @@ -95,8 +95,8 @@ abstract class BaseInstaller /** * Replace vars in a path * - * @param string $path - * @param array $vars + * @param string $path + * @param array $vars * @return string */ protected function templatePath($path, array $vars = array()) @@ -121,7 +121,7 @@ abstract class BaseInstaller * @param string $name * @param string $type * @param string $vendor = NULL - * @return string + * @return string|false */ protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL) { diff --git a/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php index 71ee2efc9..dda90a4e9 100644 --- a/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php @@ -2,6 +2,7 @@ namespace Composer\Installers; use Composer\DependencyResolver\Pool; +use Composer\Semver\Constraint\Constraint; class CakePHPInstaller extends BaseInstaller { @@ -49,14 +50,6 @@ class CakePHPInstaller extends BaseInstaller */ protected function matchesCakeVersion($matcher, $version) { - if (class_exists('Composer\Semver\Constraint\MultiConstraint')) { - $multiClass = 'Composer\Semver\Constraint\MultiConstraint'; - $constraintClass = 'Composer\Semver\Constraint\Constraint'; - } else { - $multiClass = 'Composer\Package\LinkConstraint\MultiConstraint'; - $constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint'; - } - $repositoryManager = $this->composer->getRepositoryManager(); if (! $repositoryManager) { return false; @@ -67,6 +60,6 @@ class CakePHPInstaller extends BaseInstaller return false; } - return $repos->findPackage('cakephp/cakephp', new $constraintClass($matcher, $version)) !== null; + return $repos->findPackage('cakephp/cakephp', new Constraint($matcher, $version)) !== null; } } diff --git a/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php b/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php index c7816dfce..053f3ffd7 100644 --- a/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php @@ -12,9 +12,7 @@ class CockpitInstaller extends BaseInstaller * * Strip `module-` prefix from package name. * - * @param array @vars - * - * @return array + * {@inheritDoc} */ public function inflectPackageVars($vars) { diff --git a/vendor/composer/installers/src/Composer/Installers/Installer.php b/vendor/composer/installers/src/Composer/Installers/Installer.php index d1d43b943..5869c1776 100644 --- a/vendor/composer/installers/src/Composer/Installers/Installer.php +++ b/vendor/composer/installers/src/Composer/Installers/Installer.php @@ -9,6 +9,7 @@ use Composer\IO\IOInterface; use Composer\Package\PackageInterface; use Composer\Repository\InstalledRepositoryInterface; use Composer\Util\Filesystem; +use React\Promise\PromiseInterface; class Installer extends LibraryInstaller { @@ -87,6 +88,7 @@ class Installer extends LibraryInstaller 'radphp' => 'RadPHPInstaller', 'phifty' => 'PhiftyInstaller', 'porto' => 'PortoInstaller', + 'processwire' => 'ProcessWireInstaller', 'redaxo' => 'RedaxoInstaller', 'redaxo5' => 'Redaxo5Installer', 'reindex' => 'ReIndexInstaller', @@ -95,6 +97,7 @@ class Installer extends LibraryInstaller 'sitedirect' => 'SiteDirectInstaller', 'silverstripe' => 'SilverStripeInstaller', 'smf' => 'SMFInstaller', + 'starbug' => 'StarbugInstaller', 'sydes' => 'SyDESInstaller', 'sylius' => 'SyliusInstaller', 'symfony1' => 'Symfony1Installer', @@ -160,9 +163,23 @@ class Installer extends LibraryInstaller public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package) { - parent::uninstall($repo, $package); $installPath = $this->getPackageBasePath($package); - $this->io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? 'deleted' : 'not deleted')); + $io = $this->io; + $outputStatus = function () use ($io, $installPath) { + $io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? 'deleted' : 'not deleted')); + }; + + $promise = parent::uninstall($repo, $package); + + // Composer v2 might return a promise here + if ($promise instanceof PromiseInterface) { + return $promise->then($outputStatus); + } + + // If not, execute the code right away as parent::uninstall executed synchronously (composer v1, or v2 without async) + $outputStatus(); + + return null; } /** @@ -184,23 +201,20 @@ class Installer extends LibraryInstaller /** * Finds a supported framework type if it exists and returns it * - * @param string $type - * @return string + * @param string $type + * @return string|false */ protected function findFrameworkType($type) { - $frameworkType = false; - krsort($this->supportedTypes); foreach ($this->supportedTypes as $key => $val) { if ($key === substr($type, 0, strlen($key))) { - $frameworkType = substr($type, 0, strlen($key)); - break; + return substr($type, 0, strlen($key)); } } - return $frameworkType; + return false; } /** diff --git a/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php index 75dbe71b3..05317995f 100644 --- a/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php @@ -18,6 +18,7 @@ class MoodleInstaller extends BaseInstaller 'cachestore' => 'cache/stores/{$name}/', 'cachelock' => 'cache/locks/{$name}/', 'calendartype' => 'calendar/type/{$name}/', + 'fileconverter' => 'files/converter/{$name}/', 'format' => 'course/format/{$name}/', 'coursereport' => 'course/report/{$name}/', 'customcertelement' => 'mod/customcert/element/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php b/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php index 49940ff6d..1797a22cf 100644 --- a/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php @@ -18,7 +18,7 @@ class OxidInstaller extends BaseInstaller * * @param PackageInterface $package * @param string $frameworkType - * @return void + * @return string */ public function getInstallPath(PackageInterface $package, $frameworkType = '') { diff --git a/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php b/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php index 83ef9d091..8626a9bc2 100644 --- a/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php @@ -13,9 +13,7 @@ class SyDESInstaller extends BaseInstaller * * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present. * - * @param array @vars - * - * @return array + * {@inerhitDoc} */ public function inflectPackageVars($vars) { diff --git a/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php b/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php index 108def151..4f79a45f9 100644 --- a/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php @@ -6,7 +6,25 @@ namespace Composer\Installers; */ class TaoInstaller extends BaseInstaller { + const EXTRA_TAO_EXTENSION_NAME = 'tao-extension-name'; + protected $locations = array( 'extension' => '{$name}' ); + + public function inflectPackageVars($vars) + { + $extra = $this->package->getExtra(); + + if (array_key_exists(self::EXTRA_TAO_EXTENSION_NAME, $extra)) { + $vars['name'] = $extra[self::EXTRA_TAO_EXTENSION_NAME]; + return $vars; + } + + $vars['name'] = str_replace('extension-', '', $vars['name']); + $vars['name'] = str_replace('-', ' ', $vars['name']); + $vars['name'] = lcfirst(str_replace(' ', '', ucwords($vars['name']))); + + return $vars; + } } diff --git a/vendor/doctrine/annotations/CHANGELOG.md b/vendor/doctrine/annotations/CHANGELOG.md index c09ebe601..0b0ba1a71 100644 --- a/vendor/doctrine/annotations/CHANGELOG.md +++ b/vendor/doctrine/annotations/CHANGELOG.md @@ -1,5 +1,52 @@ ## Changelog +### 1.6.1 + +This release fixes an issue in which annotations such as `@foo-bar` +and `@foo-` were incorrectly recognised as valid, and both erroneously +parsed as `@foo`. + +Any annotation with `@name-*` format will now silently be ignored, +allowing vendor-specific annotations to be prefixed with the tool +name. + +Total issues resolved: **3** + +- [165: Update the composer branch alias](https://github.com/doctrine/annotations/pull/165) thanks to @mikeSimonson +- [209: Change Annotation::value typehint to mixed](https://github.com/doctrine/annotations/pull/209) thanks to @malarzm +- [257: Skip parsing annotations containing dashes, such as `@Foo-bar`, or `@Foo-`](https://github.com/doctrine/annotations/pull/257) thanks to @Ocramius + +### 1.6.0 + +This release brings a new endpoint that make sure that you can't shoot yourself in the foot by calling ```registerLoader``` multiple times and a few tests improvements. + +Total issues resolved: **7** + +- [145: Memory leak in AnnotationRegistry::registerLoader() when called multiple times](https://github.com/doctrine/annotations/issues/145) thanks to @TriAnMan +- [146: Import error on @experimental Annotation](https://github.com/doctrine/annotations/issues/146) thanks to @aturki +- [147: Ignoring @experimental annotation used by Symfony 3.3 CacheAdapter](https://github.com/doctrine/annotations/pull/147) thanks to @aturki +- [151: Remove duplicate code in `DCOM58Test`](https://github.com/doctrine/annotations/pull/151) thanks to @tuanphpvn +- [161: Prevent loading class_exists multiple times](https://github.com/doctrine/annotations/pull/161) thanks to @jrjohnson +- [162: Add registerUniqueLoader to AnnotationRegistry](https://github.com/doctrine/annotations/pull/162) thanks to @jrjohnson +- [163: Use assertDirectoryExists and assertDirectoryNotExists](https://github.com/doctrine/annotations/pull/163) thanks to @carusogabriel + +Thanks to everyone involved in this release. + +### 1.5.0 + +This release increments the minimum supported PHP version to 7.1.0. + +Also, HHVM official support has been dropped. + +Some noticeable performance improvements to annotation autoloading +have been applied, making failed annotation autoloading less heavy +on the filesystem access. + +- [133: Add @throws annotation in AnnotationReader#__construct()](https://github.com/doctrine/annotations/issues/133) thanks to @SenseException +- [134: Require PHP 7.1, drop HHVM support](https://github.com/doctrine/annotations/issues/134) thanks to @lcobucci +- [135: Prevent the same loader from being registered twice](https://github.com/doctrine/annotations/issues/135) thanks to @jrjohnson +- [137: #135 optimise multiple class load attempts in AnnotationRegistry](https://github.com/doctrine/annotations/issues/137) thanks to @Ocramius + ### 1.4.0 diff --git a/vendor/doctrine/annotations/README.md b/vendor/doctrine/annotations/README.md index 8f89ea545..ddeddd22f 100644 --- a/vendor/doctrine/annotations/README.md +++ b/vendor/doctrine/annotations/README.md @@ -1,16 +1,21 @@ # Doctrine Annotations -[![Build Status](https://travis-ci.org/doctrine/annotations.svg?branch=master)](https://travis-ci.org/doctrine/annotations) +[![Build Status](https://github.com/doctrine/annotations/workflows/Continuous%20Integration/badge.svg?label=build)](https://github.com/doctrine/persistence/actions) [![Dependency Status](https://www.versioneye.com/package/php--doctrine--annotations/badge.png)](https://www.versioneye.com/package/php--doctrine--annotations) [![Reference Status](https://www.versioneye.com/php/doctrine:annotations/reference_badge.svg)](https://www.versioneye.com/php/doctrine:annotations/references) [![Total Downloads](https://poser.pugx.org/doctrine/annotations/downloads.png)](https://packagist.org/packages/doctrine/annotations) -[![Latest Stable Version](https://poser.pugx.org/doctrine/annotations/v/stable.png)](https://packagist.org/packages/doctrine/annotations) +[![Latest Stable Version](https://img.shields.io/packagist/v/doctrine/annotations.svg?label=stable)](https://packagist.org/packages/doctrine/annotations) Docblock Annotations Parser library (extracted from [Doctrine Common](https://github.com/doctrine/common)). ## Documentation -See the [doctrine-project website](http://docs.doctrine-project.org/projects/doctrine-common/en/latest/reference/annotations.html). +See the [doctrine-project website](https://www.doctrine-project.org/projects/doctrine-annotations/en/latest/index.html). + +## Contributing + +When making a pull request, make sure your changes follow the +[Coding Standard Guidelines](https://www.doctrine-project.org/projects/doctrine-coding-standard/en/current/reference/index.html#introduction). ## Changelog diff --git a/vendor/doctrine/annotations/composer.json b/vendor/doctrine/annotations/composer.json index 6a2719b34..e14ce9350 100644 --- a/vendor/doctrine/annotations/composer.json +++ b/vendor/doctrine/annotations/composer.json @@ -3,7 +3,7 @@ "type": "library", "description": "Docblock Annotations Parser", "keywords": ["annotations", "docblock", "parser"], - "homepage": "http://www.doctrine-project.org", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", "license": "MIT", "authors": [ {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, @@ -13,22 +13,30 @@ {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} ], "require": { - "php": "^5.6 || ^7.0", + "php": "^7.1 || ^8.0", + "ext-tokenizer": "*", "doctrine/lexer": "1.*" }, "require-dev": { "doctrine/cache": "1.*", - "phpunit/phpunit": "^5.7" + "doctrine/coding-standard": "^6.0 || ^8.1", + "phpstan/phpstan": "^0.12.20", + "phpunit/phpunit": "^7.5 || ^9.1.5" + }, + "config": { + "sort-packages": true }, "autoload": { "psr-4": { "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" } }, "autoload-dev": { - "psr-4": { "Doctrine\\Tests\\Common\\Annotations\\": "tests/Doctrine/Tests/Common/Annotations" } - }, - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } + "psr-4": { + "Doctrine\\Performance\\Common\\Annotations\\": "tests/Doctrine/Performance/Common/Annotations", + "Doctrine\\Tests\\Common\\Annotations\\": "tests/Doctrine/Tests/Common/Annotations" + }, + "files": [ + "tests/Doctrine/Tests/Common/Annotations/Fixtures/functions.php", + "tests/Doctrine/Tests/Common/Annotations/Fixtures/SingleClassLOC1000.php" + ] } } diff --git a/vendor/doctrine/annotations/docs/en/annotations.rst b/vendor/doctrine/annotations/docs/en/annotations.rst new file mode 100644 index 000000000..648ab26ed --- /dev/null +++ b/vendor/doctrine/annotations/docs/en/annotations.rst @@ -0,0 +1,271 @@ +Handling Annotations +==================== + +There are several different approaches to handling annotations in PHP. +Doctrine Annotations maps docblock annotations to PHP classes. Because +not all docblock annotations are used for metadata purposes a filter is +applied to ignore or skip classes that are not Doctrine annotations. + +Take a look at the following code snippet: + +.. code-block:: php + + namespace MyProject\Entities; + + use Doctrine\ORM\Mapping AS ORM; + use Symfony\Component\Validator\Constraints AS Assert; + + /** + * @author Benjamin Eberlei + * @ORM\Entity + * @MyProject\Annotations\Foobarable + */ + class User + { + /** + * @ORM\Id @ORM\Column @ORM\GeneratedValue + * @dummy + * @var int + */ + private $id; + + /** + * @ORM\Column(type="string") + * @Assert\NotEmpty + * @Assert\Email + * @var string + */ + private $email; + } + +In this snippet you can see a variety of different docblock annotations: + +- Documentation annotations such as ``@var`` and ``@author``. These + annotations are ignored and never considered for throwing an + exception due to wrongly used annotations. +- Annotations imported through use statements. The statement ``use + Doctrine\ORM\Mapping AS ORM`` makes all classes under that namespace + available as ``@ORM\ClassName``. Same goes for the import of + ``@Assert``. +- The ``@dummy`` annotation. It is not a documentation annotation and + not ignored. For Doctrine Annotations it is not entirely clear how + to handle this annotation. Depending on the configuration an exception + (unknown annotation) will be thrown when parsing this annotation. +- The fully qualified annotation ``@MyProject\Annotations\Foobarable``. + This is transformed directly into the given class name. + +How are these annotations loaded? From looking at the code you could +guess that the ORM Mapping, Assert Validation and the fully qualified +annotation can just be loaded using +the defined PHP autoloaders. This is not the case however: For error +handling reasons every check for class existence inside the +``AnnotationReader`` sets the second parameter $autoload +of ``class_exists($name, $autoload)`` to false. To work flawlessly the +``AnnotationReader`` requires silent autoloaders which many autoloaders are +not. Silent autoloading is NOT part of the `PSR-0 specification +`_ +for autoloading. + +This is why Doctrine Annotations uses its own autoloading mechanism +through a global registry. If you are wondering about the annotation +registry being global, there is no other way to solve the architectural +problems of autoloading annotation classes in a straightforward fashion. +Additionally if you think about PHP autoloading then you recognize it is +a global as well. + +To anticipate the configuration section, making the above PHP class work +with Doctrine Annotations requires this setup: + +.. code-block:: php + + use Doctrine\Common\Annotations\AnnotationReader; + use Doctrine\Common\Annotations\AnnotationRegistry; + + AnnotationRegistry::registerFile("/path/to/doctrine/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php"); + AnnotationRegistry::registerAutoloadNamespace("Symfony\Component\Validator\Constraint", "/path/to/symfony/src"); + AnnotationRegistry::registerAutoloadNamespace("MyProject\Annotations", "/path/to/myproject/src"); + + $reader = new AnnotationReader(); + AnnotationReader::addGlobalIgnoredName('dummy'); + +The second block with the annotation registry calls registers all the +three different annotation namespaces that are used. +Doctrine Annotations saves all its annotations in a single file, that is +why ``AnnotationRegistry#registerFile`` is used in contrast to +``AnnotationRegistry#registerAutoloadNamespace`` which creates a PSR-0 +compatible loading mechanism for class to file names. + +In the third block, we create the actual ``AnnotationReader`` instance. +Note that we also add ``dummy`` to the global list of ignored +annotations for which we do not throw exceptions. Setting this is +necessary in our example case, otherwise ``@dummy`` would trigger an +exception to be thrown during the parsing of the docblock of +``MyProject\Entities\User#id``. + +Setup and Configuration +----------------------- + +To use the annotations library is simple, you just need to create a new +``AnnotationReader`` instance: + +.. code-block:: php + + $reader = new \Doctrine\Common\Annotations\AnnotationReader(); + +This creates a simple annotation reader with no caching other than in +memory (in php arrays). Since parsing docblocks can be expensive you +should cache this process by using a caching reader. + +You can use a file caching reader, but please note it is deprecated to +do so: + +.. code-block:: php + + use Doctrine\Common\Annotations\FileCacheReader; + use Doctrine\Common\Annotations\AnnotationReader; + + $reader = new FileCacheReader( + new AnnotationReader(), + "/path/to/cache", + $debug = true + ); + +If you set the ``debug`` flag to ``true`` the cache reader will check +for changes in the original files, which is very important during +development. If you don't set it to ``true`` you have to delete the +directory to clear the cache. This gives faster performance, however +should only be used in production, because of its inconvenience during +development. + +You can also use one of the ``Doctrine\Common\Cache\Cache`` cache +implementations to cache the annotations: + +.. code-block:: php + + use Doctrine\Common\Annotations\AnnotationReader; + use Doctrine\Common\Annotations\CachedReader; + use Doctrine\Common\Cache\ApcCache; + + $reader = new CachedReader( + new AnnotationReader(), + new ApcCache(), + $debug = true + ); + +The ``debug`` flag is used here as well to invalidate the cache files +when the PHP class with annotations changed and should be used during +development. + +.. warning :: + + The ``AnnotationReader`` works and caches under the + assumption that all annotations of a doc-block are processed at + once. That means that annotation classes that do not exist and + aren't loaded and cannot be autoloaded (using the + AnnotationRegistry) would never be visible and not accessible if a + cache is used unless the cache is cleared and the annotations + requested again, this time with all annotations defined. + +By default the annotation reader returns a list of annotations with +numeric indexes. If you want your annotations to be indexed by their +class name you can wrap the reader in an ``IndexedReader``: + +.. code-block:: php + + use Doctrine\Common\Annotations\AnnotationReader; + use Doctrine\Common\Annotations\IndexedReader; + + $reader = new IndexedReader(new AnnotationReader()); + +.. warning:: + + You should never wrap the indexed reader inside a cached reader, + only the other way around. This way you can re-use the cache with + indexed or numeric keys, otherwise your code may experience failures + due to caching in a numerical or indexed format. + +Registering Annotations +~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in the introduction, Doctrine Annotations uses its own +autoloading mechanism to determine if a given annotation has a +corresponding PHP class that can be autoloaded. For annotation +autoloading you have to configure the +``Doctrine\Common\Annotations\AnnotationRegistry``. There are three +different mechanisms to configure annotation autoloading: + +- Calling ``AnnotationRegistry#registerFile($file)`` to register a file + that contains one or more annotation classes. +- Calling ``AnnotationRegistry#registerNamespace($namespace, $dirs = + null)`` to register that the given namespace contains annotations and + that their base directory is located at the given $dirs or in the + include path if ``NULL`` is passed. The given directories should *NOT* + be the directory where classes of the namespace are in, but the base + directory of the root namespace. The AnnotationRegistry uses a + namespace to directory separator approach to resolve the correct path. +- Calling ``AnnotationRegistry#registerLoader($callable)`` to register + an autoloader callback. The callback accepts the class as first and + only parameter and has to return ``true`` if the corresponding file + was found and included. + +.. note:: + + Loaders have to fail silently, if a class is not found even if it + matches for example the namespace prefix of that loader. Never is a + loader to throw a warning or exception if the loading failed + otherwise parsing doc block annotations will become a huge pain. + +A sample loader callback could look like: + +.. code-block:: php + + use Doctrine\Common\Annotations\AnnotationRegistry; + use Symfony\Component\ClassLoader\UniversalClassLoader; + + AnnotationRegistry::registerLoader(function($class) { + $file = str_replace("\\", DIRECTORY_SEPARATOR, $class) . ".php"; + + if (file_exists("/my/base/path/" . $file)) { + // file_exists() makes sure that the loader fails silently + require "/my/base/path/" . $file; + } + }); + + $loader = new UniversalClassLoader(); + AnnotationRegistry::registerLoader(array($loader, "loadClass")); + + +Ignoring missing exceptions +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default an exception is thrown from the ``AnnotationReader`` if an +annotation was found that: + +- is not part of the list of ignored "documentation annotations"; +- was not imported through a use statement; +- is not a fully qualified class that exists. + +You can disable this behavior for specific names if your docblocks do +not follow strict requirements: + +.. code-block:: php + + $reader = new \Doctrine\Common\Annotations\AnnotationReader(); + AnnotationReader::addGlobalIgnoredName('foo'); + +PHP Imports +~~~~~~~~~~~ + +By default the annotation reader parses the use-statement of a php file +to gain access to the import rules and register them for the annotation +processing. Only if you are using PHP Imports can you validate the +correct usage of annotations and throw exceptions if you misspelled an +annotation. This mechanism is enabled by default. + +To ease the upgrade path, we still allow you to disable this mechanism. +Note however that we will remove this in future versions: + +.. code-block:: php + + $reader = new \Doctrine\Common\Annotations\AnnotationReader(); + $reader->setEnabledPhpImports(false); diff --git a/vendor/doctrine/annotations/docs/en/custom.rst b/vendor/doctrine/annotations/docs/en/custom.rst new file mode 100644 index 000000000..11fbe1a31 --- /dev/null +++ b/vendor/doctrine/annotations/docs/en/custom.rst @@ -0,0 +1,443 @@ +Custom Annotation Classes +========================= + +If you want to define your own annotations, you just have to group them +in a namespace and register this namespace in the ``AnnotationRegistry``. +Annotation classes have to contain a class-level docblock with the text +``@Annotation``: + +.. code-block:: php + + namespace MyCompany\Annotations; + + /** @Annotation */ + class Bar + { + // some code + } + +Inject annotation values +------------------------ + +The annotation parser checks if the annotation constructor has arguments, +if so then it will pass the value array, otherwise it will try to inject +values into public properties directly: + + +.. code-block:: php + + namespace MyCompany\Annotations; + + /** + * @Annotation + * + * Some Annotation using a constructor + */ + class Bar + { + private $foo; + + public function __construct(array $values) + { + $this->foo = $values['foo']; + } + } + + /** + * @Annotation + * + * Some Annotation without a constructor + */ + class Foo + { + public $bar; + } + +Optional: Constructors with Named Parameters +-------------------------------------------- + +Starting with Annotations v1.11 a new annotation instantiation strategy +is available that aims at compatibility of Annotation classes with the PHP 8 +attribute feature. You need to declare a constructor with regular parameter +names that match the named arguments in the annotation syntax. + +To enable this feature, you can tag your annotation class with +``@NamedArgumentConstructor`` (available from v1.12) or implement the +``Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation`` interface +(available from v1.11 and deprecated as of v1.12). +When using the ``@NamedArgumentConstructor`` tag, the first argument of the +constructor is considered as the default one. + + +Usage with the ``@NamedArgumentContrustor`` tag + +.. code-block:: php + + namespace MyCompany\Annotations; + + /** + * @Annotation + * @NamedArgumentConstructor + */ + class Bar implements NamedArgumentConstructorAnnotation + { + private $foo; + + public function __construct(string $foo) + { + $this->foo = $foo; + } + } + + /** Usable with @Bar(foo="baz") */ + /** Usable with @Bar("baz") */ + +In combination with PHP 8's constructor property promotion feature +you can simplify this to: + +.. code-block:: php + + namespace MyCompany\Annotations; + + /** + * @Annotation + * @NamedArgumentConstructor + */ + class Bar implements NamedArgumentConstructorAnnotation + { + public function __construct(private string $foo) {} + } + + +Usage with the +``Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation`` +interface (v1.11, deprecated as of v1.12): +.. code-block:: php + + namespace MyCompany\Annotations; + + use Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation; + + /** @Annotation */ + class Bar implements NamedArgumentConstructorAnnotation + { + private $foo; + + public function __construct(private string $foo) {} + } + + /** Usable with @Bar(foo="baz") */ + +Annotation Target +----------------- + +``@Target`` indicates the kinds of class elements to which an annotation +type is applicable. Then you could define one or more targets: + +- ``CLASS`` Allowed in class docblocks +- ``PROPERTY`` Allowed in property docblocks +- ``METHOD`` Allowed in the method docblocks +- ``FUNCTION`` Allowed in function dockblocks +- ``ALL`` Allowed in class, property, method and function docblocks +- ``ANNOTATION`` Allowed inside other annotations + +If the annotations is not allowed in the current context, an +``AnnotationException`` is thrown. + +.. code-block:: php + + namespace MyCompany\Annotations; + + /** + * @Annotation + * @Target({"METHOD","PROPERTY"}) + */ + class Bar + { + // some code + } + + /** + * @Annotation + * @Target("CLASS") + */ + class Foo + { + // some code + } + +Attribute types +--------------- + +The annotation parser checks the given parameters using the phpdoc +annotation ``@var``, The data type could be validated using the ``@var`` +annotation on the annotation properties or using the ``@Attributes`` and +``@Attribute`` annotations. + +If the data type does not match you get an ``AnnotationException`` + +.. code-block:: php + + namespace MyCompany\Annotations; + + /** + * @Annotation + * @Target({"METHOD","PROPERTY"}) + */ + class Bar + { + /** @var mixed */ + public $mixed; + + /** @var boolean */ + public $boolean; + + /** @var bool */ + public $bool; + + /** @var float */ + public $float; + + /** @var string */ + public $string; + + /** @var integer */ + public $integer; + + /** @var array */ + public $array; + + /** @var SomeAnnotationClass */ + public $annotation; + + /** @var array */ + public $arrayOfIntegers; + + /** @var array */ + public $arrayOfAnnotations; + } + + /** + * @Annotation + * @Target({"METHOD","PROPERTY"}) + * @Attributes({ + * @Attribute("stringProperty", type = "string"), + * @Attribute("annotProperty", type = "SomeAnnotationClass"), + * }) + */ + class Foo + { + public function __construct(array $values) + { + $this->stringProperty = $values['stringProperty']; + $this->annotProperty = $values['annotProperty']; + } + + // some code + } + +Annotation Required +------------------- + +``@Required`` indicates that the field must be specified when the +annotation is used. If it is not used you get an ``AnnotationException`` +stating that this value can not be null. + +Declaring a required field: + +.. code-block:: php + + /** + * @Annotation + * @Target("ALL") + */ + class Foo + { + /** @Required */ + public $requiredField; + } + +Usage: + +.. code-block:: php + + /** @Foo(requiredField="value") */ + public $direction; // Valid + + /** @Foo */ + public $direction; // Required field missing, throws an AnnotationException + + +Enumerated values +----------------- + +- An annotation property marked with ``@Enum`` is a field that accepts a + fixed set of scalar values. +- You should use ``@Enum`` fields any time you need to represent fixed + values. +- The annotation parser checks the given value and throws an + ``AnnotationException`` if the value does not match. + + +Declaring an enumerated property: + +.. code-block:: php + + /** + * @Annotation + * @Target("ALL") + */ + class Direction + { + /** + * @Enum({"NORTH", "SOUTH", "EAST", "WEST"}) + */ + public $value; + } + +Annotation usage: + +.. code-block:: php + + /** @Direction("NORTH") */ + public $direction; // Valid value + + /** @Direction("NORTHEAST") */ + public $direction; // Invalid value, throws an AnnotationException + + +Constants +--------- + +The use of constants and class constants is available on the annotations +parser. + +The following usages are allowed: + +.. code-block:: php + + namespace MyCompany\Entity; + + use MyCompany\Annotations\Foo; + use MyCompany\Annotations\Bar; + use MyCompany\Entity\SomeClass; + + /** + * @Foo(PHP_EOL) + * @Bar(Bar::FOO) + * @Foo({SomeClass::FOO, SomeClass::BAR}) + * @Bar({SomeClass::FOO_KEY = SomeClass::BAR_VALUE}) + */ + class User + { + } + + +Be careful with constants and the cache ! + +.. note:: + + The cached reader will not re-evaluate each time an annotation is + loaded from cache. When a constant is changed the cache must be + cleaned. + + +Usage +----- + +Using the library API is simple. Using the annotations described in the +previous section, you can now annotate other classes with your +annotations: + +.. code-block:: php + + namespace MyCompany\Entity; + + use MyCompany\Annotations\Foo; + use MyCompany\Annotations\Bar; + + /** + * @Foo(bar="foo") + * @Bar(foo="bar") + */ + class User + { + } + +Now we can write a script to get the annotations above: + +.. code-block:: php + + $reflClass = new ReflectionClass('MyCompany\Entity\User'); + $classAnnotations = $reader->getClassAnnotations($reflClass); + + foreach ($classAnnotations AS $annot) { + if ($annot instanceof \MyCompany\Annotations\Foo) { + echo $annot->bar; // prints "foo"; + } else if ($annot instanceof \MyCompany\Annotations\Bar) { + echo $annot->foo; // prints "bar"; + } + } + +You have a complete API for retrieving annotation class instances from a +class, property or method docblock: + + +Reader API +~~~~~~~~~~ + +Access all annotations of a class +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: php + + public function getClassAnnotations(\ReflectionClass $class); + +Access one annotation of a class +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: php + + public function getClassAnnotation(\ReflectionClass $class, $annotationName); + +Access all annotations of a method +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: php + + public function getMethodAnnotations(\ReflectionMethod $method); + +Access one annotation of a method +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: php + + public function getMethodAnnotation(\ReflectionMethod $method, $annotationName); + +Access all annotations of a property +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: php + + public function getPropertyAnnotations(\ReflectionProperty $property); + +Access one annotation of a property +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: php + + public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName); + +Access all annotations of a function +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: php + + public function getFunctionAnnotations(\ReflectionFunction $property); + +Access one annotation of a function +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: php + + public function getFunctionAnnotation(\ReflectionFunction $property, $annotationName); diff --git a/vendor/doctrine/annotations/docs/en/index.rst b/vendor/doctrine/annotations/docs/en/index.rst new file mode 100644 index 000000000..fd001f48e --- /dev/null +++ b/vendor/doctrine/annotations/docs/en/index.rst @@ -0,0 +1,101 @@ +Introduction +============ + +Doctrine Annotations allows to implement custom annotation +functionality for PHP classes and functions. + +.. code-block:: php + + class Foo + { + /** + * @MyAnnotation(myProperty="value") + */ + private $bar; + } + +Annotations aren't implemented in PHP itself which is why this component +offers a way to use the PHP doc-blocks as a place for the well known +annotation syntax using the ``@`` char. + +Annotations in Doctrine are used for the ORM configuration to build the +class mapping, but it can be used in other projects for other purposes +too. + +Installation +============ + +You can install the Annotation component with composer: + +.. code-block:: + +   $ composer require doctrine/annotations + +Create an annotation class +========================== + +An annotation class is a representation of the later used annotation +configuration in classes. The annotation class of the previous example +looks like this: + +.. code-block:: php + + /** + * @Annotation + */ + final class MyAnnotation + { + public $myProperty; + } + +The annotation class is declared as an annotation by ``@Annotation``. + +:ref:`Read more about custom annotations. ` + +Reading annotations +=================== + +The access to the annotations happens by reflection of the class or function +containing them. There are multiple reader-classes implementing the +``Doctrine\Common\Annotations\Reader`` interface, that can access the +annotations of a class. A common one is +``Doctrine\Common\Annotations\AnnotationReader``: + +.. code-block:: php + + use Doctrine\Common\Annotations\AnnotationReader; + use Doctrine\Common\Annotations\AnnotationRegistry; + + // Deprecated and will be removed in 2.0 but currently needed + AnnotationRegistry::registerLoader('class_exists'); + + $reflectionClass = new ReflectionClass(Foo::class); + $property = $reflectionClass->getProperty('bar'); + + $reader = new AnnotationReader(); + $myAnnotation = $reader->getPropertyAnnotation( + $property, + MyAnnotation::class + ); + + echo $myAnnotation->myProperty; // result: "value" + +Note that ``AnnotationRegistry::registerLoader('class_exists')`` only works +if you already have an autoloader configured (i.e. composer autoloader). +Otherwise, :ref:`please take a look to the other annotation autoload mechanisms `. + +A reader has multiple methods to access the annotations of a class or +function. + +:ref:`Read more about handling annotations. ` + +IDE Support +----------- + +Some IDEs already provide support for annotations: + +- Eclipse via the `Symfony2 Plugin `_ +- PhpStorm via the `PHP Annotations Plugin `_ or the `Symfony Plugin `_ + +.. _Read more about handling annotations.: annotations +.. _Read more about custom annotations.: custom diff --git a/vendor/doctrine/annotations/docs/en/sidebar.rst b/vendor/doctrine/annotations/docs/en/sidebar.rst new file mode 100644 index 000000000..6f5d13c46 --- /dev/null +++ b/vendor/doctrine/annotations/docs/en/sidebar.rst @@ -0,0 +1,6 @@ +.. toctree:: + :depth: 3 + + index + annotations + custom diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php index a79a0f8f0..750270e42 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php @@ -1,47 +1,27 @@ . - */ namespace Doctrine\Common\Annotations; +use BadMethodCallException; + +use function sprintf; + /** * Annotations class. - * - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel */ class Annotation { /** * Value property. Common among all derived classes. * - * @var string + * @var mixed */ public $value; /** - * Constructor. - * - * @param array $data Key-value for properties to be defined in this class. + * @param array $data Key-value for properties to be defined in this class. */ - public final function __construct(array $data) + final public function __construct(array $data) { foreach ($data as $key => $value) { $this->$key = $value; @@ -53,12 +33,12 @@ class Annotation * * @param string $name Unknown property name. * - * @throws \BadMethodCallException + * @throws BadMethodCallException */ public function __get($name) { - throw new \BadMethodCallException( - sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this)) + throw new BadMethodCallException( + sprintf("Unknown property '%s' on annotation '%s'.", $name, static::class) ); } @@ -68,12 +48,12 @@ class Annotation * @param string $name Unknown property name. * @param mixed $value Property value. * - * @throws \BadMethodCallException + * @throws BadMethodCallException */ public function __set($name, $value) { - throw new \BadMethodCallException( - sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this)) + throw new BadMethodCallException( + sprintf("Unknown property '%s' on annotation '%s'.", $name, static::class) ); } } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attribute.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attribute.php index dbef6df08..b1f851400 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attribute.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attribute.php @@ -1,47 +1,21 @@ . - */ - namespace Doctrine\Common\Annotations\Annotation; /** * Annotation that can be used to signal to the parser * to check the attribute type during the parsing process. * - * @author Fabio B. Silva - * * @Annotation */ final class Attribute { - /** - * @var string - */ + /** @var string */ public $name; - /** - * @var string - */ + /** @var string */ public $type; - /** - * @var boolean - */ + /** @var bool */ public $required = false; } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attributes.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attributes.php index 53134e309..8f758f3f7 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attributes.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attributes.php @@ -1,37 +1,15 @@ . - */ - namespace Doctrine\Common\Annotations\Annotation; /** * Annotation that can be used to signal to the parser * to check the types of all declared attributes during the parsing process. * - * @author Fabio B. Silva - * * @Annotation */ final class Attributes { - /** - * @var array - */ + /** @var array */ public $value; } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Enum.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Enum.php index e122a7535..35d6410b1 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Enum.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Enum.php @@ -1,32 +1,20 @@ . - */ - namespace Doctrine\Common\Annotations\Annotation; +use InvalidArgumentException; + +use function get_class; +use function gettype; +use function in_array; +use function is_object; +use function is_scalar; +use function sprintf; + /** * Annotation that can be used to signal to the parser * to check the available values during the parsing process. * - * @since 2.4 - * @author Fabio B. Silva - * * @Annotation * @Attributes({ * @Attribute("value", required = true, type = "array"), @@ -35,34 +23,30 @@ namespace Doctrine\Common\Annotations\Annotation; */ final class Enum { - /** - * @var array - */ + /** @phpstan-var list */ public $value; /** * Literal target declaration. * - * @var array + * @var mixed[] */ public $literal; /** - * Annotation constructor. + * @throws InvalidArgumentException * - * @param array $values - * - * @throws \InvalidArgumentException + * @phpstan-param array{literal?: mixed[], value: list} $values */ public function __construct(array $values) { - if ( ! isset($values['literal'])) { - $values['literal'] = array(); + if (! isset($values['literal'])) { + $values['literal'] = []; } foreach ($values['value'] as $var) { - if( ! is_scalar($var)) { - throw new \InvalidArgumentException(sprintf( + if (! is_scalar($var)) { + throw new InvalidArgumentException(sprintf( '@Enum supports only scalar values "%s" given.', is_object($var) ? get_class($var) : gettype($var) )); @@ -70,15 +54,16 @@ final class Enum } foreach ($values['literal'] as $key => $var) { - if( ! in_array($key, $values['value'])) { - throw new \InvalidArgumentException(sprintf( + if (! in_array($key, $values['value'])) { + throw new InvalidArgumentException(sprintf( 'Undefined enumerator value "%s" for literal "%s".', - $key , $var + $key, + $var )); } } - $this->value = $values['value']; - $this->literal = $values['literal']; + $this->value = $values['value']; + $this->literal = $values['literal']; } } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php index 175226a67..ae60f7d5b 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php @@ -1,52 +1,41 @@ . - */ namespace Doctrine\Common\Annotations\Annotation; +use RuntimeException; + +use function is_array; +use function is_string; +use function json_encode; +use function sprintf; + /** * Annotation that can be used to signal to the parser to ignore specific * annotations during the parsing process. * * @Annotation - * @author Johannes M. Schmitt */ final class IgnoreAnnotation { - /** - * @var array - */ + /** @phpstan-var list */ public $names; /** - * Constructor. + * @throws RuntimeException * - * @param array $values - * - * @throws \RuntimeException + * @phpstan-param array{value: string|list} $values */ public function __construct(array $values) { if (is_string($values['value'])) { - $values['value'] = array($values['value']); + $values['value'] = [$values['value']]; } - if (!is_array($values['value'])) { - throw new \RuntimeException(sprintf('@IgnoreAnnotation expects either a string name, or an array of strings, but got %s.', json_encode($values['value']))); + + if (! is_array($values['value'])) { + throw new RuntimeException(sprintf( + '@IgnoreAnnotation expects either a string name, or an array of strings, but got %s.', + json_encode($values['value']) + )); } $this->names = $values['value']; diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/NamedArgumentConstructor.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/NamedArgumentConstructor.php new file mode 100644 index 000000000..169060103 --- /dev/null +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/NamedArgumentConstructor.php @@ -0,0 +1,13 @@ +. - */ - namespace Doctrine\Common\Annotations\Annotation; /** * Annotation that can be used to signal to the parser * to check if that attribute is required during the parsing process. * - * @author Fabio B. Silva - * * @Annotation */ final class Required diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Target.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Target.php index f6c544535..7fd75e2bb 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Target.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Target.php @@ -1,89 +1,79 @@ . - */ - namespace Doctrine\Common\Annotations\Annotation; +use InvalidArgumentException; + +use function array_keys; +use function get_class; +use function gettype; +use function implode; +use function is_array; +use function is_object; +use function is_string; +use function sprintf; + /** * Annotation that can be used to signal to the parser * to check the annotation target during the parsing process. * - * @author Fabio B. Silva - * * @Annotation */ final class Target { - const TARGET_CLASS = 1; - const TARGET_METHOD = 2; - const TARGET_PROPERTY = 4; - const TARGET_ANNOTATION = 8; - const TARGET_ALL = 15; + public const TARGET_CLASS = 1; + public const TARGET_METHOD = 2; + public const TARGET_PROPERTY = 4; + public const TARGET_ANNOTATION = 8; + public const TARGET_FUNCTION = 16; + public const TARGET_ALL = 31; - /** - * @var array - */ - private static $map = array( + /** @var array */ + private static $map = [ 'ALL' => self::TARGET_ALL, 'CLASS' => self::TARGET_CLASS, 'METHOD' => self::TARGET_METHOD, 'PROPERTY' => self::TARGET_PROPERTY, + 'FUNCTION' => self::TARGET_FUNCTION, 'ANNOTATION' => self::TARGET_ANNOTATION, - ); + ]; - /** - * @var array - */ + /** @phpstan-var list */ public $value; /** * Targets as bitmask. * - * @var integer + * @var int */ public $targets; /** * Literal target declaration. * - * @var integer + * @var string */ public $literal; /** - * Annotation constructor. + * @throws InvalidArgumentException * - * @param array $values - * - * @throws \InvalidArgumentException + * @phpstan-param array{value?: string|list} $values */ public function __construct(array $values) { - if (!isset($values['value'])){ + if (! isset($values['value'])) { $values['value'] = null; } - if (is_string($values['value'])){ - $values['value'] = array($values['value']); + + if (is_string($values['value'])) { + $values['value'] = [$values['value']]; } - if (!is_array($values['value'])){ - throw new \InvalidArgumentException( - sprintf('@Target expects either a string value, or an array of strings, "%s" given.', + + if (! is_array($values['value'])) { + throw new InvalidArgumentException( + sprintf( + '@Target expects either a string value, or an array of strings, "%s" given.', is_object($values['value']) ? get_class($values['value']) : gettype($values['value']) ) ); @@ -91,17 +81,21 @@ final class Target $bitmask = 0; foreach ($values['value'] as $literal) { - if(!isset(self::$map[$literal])){ - throw new \InvalidArgumentException( - sprintf('Invalid Target "%s". Available targets: [%s]', - $literal, implode(', ', array_keys(self::$map))) + if (! isset(self::$map[$literal])) { + throw new InvalidArgumentException( + sprintf( + 'Invalid Target "%s". Available targets: [%s]', + $literal, + implode(', ', array_keys(self::$map)) + ) ); } + $bitmask |= self::$map[$literal]; } - $this->targets = $bitmask; - $this->value = $values['value']; - $this->literal = implode(', ', $this->value); + $this->targets = $bitmask; + $this->value = $values['value']; + $this->literal = implode(', ', $this->value); } } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php index d06fe663c..b1ea64e6f 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php @@ -1,34 +1,19 @@ . - */ namespace Doctrine\Common\Annotations; +use Exception; + +use function get_class; +use function gettype; +use function implode; +use function is_object; +use function sprintf; + /** * Description of AnnotationException - * - * @since 2.0 - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel */ -class AnnotationException extends \Exception +class AnnotationException extends Exception { /** * Creates a new AnnotationException describing a Syntax error. @@ -58,8 +43,6 @@ class AnnotationException extends \Exception * Creates a new AnnotationException describing an error which occurred during * the creation of the annotation. * - * @since 2.2 - * * @param string $message * * @return AnnotationException @@ -72,8 +55,6 @@ class AnnotationException extends \Exception /** * Creates a new AnnotationException describing a type error. * - * @since 1.1 - * * @param string $message * * @return AnnotationException @@ -86,8 +67,6 @@ class AnnotationException extends \Exception /** * Creates a new AnnotationException describing a constant semantical error. * - * @since 2.3 - * * @param string $identifier * @param string $context * @@ -105,8 +84,6 @@ class AnnotationException extends \Exception /** * Creates a new AnnotationException describing an type error of an attribute. * - * @since 2.2 - * * @param string $attributeName * @param string $annotationName * @param string $context @@ -130,8 +107,6 @@ class AnnotationException extends \Exception /** * Creates a new AnnotationException describing an required error of an attribute. * - * @since 2.2 - * * @param string $attributeName * @param string $annotationName * @param string $context @@ -153,21 +128,20 @@ class AnnotationException extends \Exception /** * Creates a new AnnotationException describing a invalid enummerator. * - * @since 2.4 - * * @param string $attributeName * @param string $annotationName * @param string $context - * @param array $available * @param mixed $given * * @return AnnotationException + * + * @phpstan-param list $available */ public static function enumeratorError($attributeName, $annotationName, $context, $available, $given) { return new self(sprintf( - '[Enum Error] Attribute "%s" of @%s declared on %s accept only [%s], but got %s.', - $attributeName, + '[Enum Error] Attribute "%s" of @%s declared on %s accepts only [%s], but got %s.', + $attributeName, $annotationName, $context, implode(', ', $available), @@ -181,7 +155,7 @@ class AnnotationException extends \Exception public static function optimizerPlusSaveComments() { return new self( - "You have to enable opcache.save_comments=1 or zend_optimizerplus.save_comments=1." + 'You have to enable opcache.save_comments=1 or zend_optimizerplus.save_comments=1.' ); } @@ -191,7 +165,7 @@ class AnnotationException extends \Exception public static function optimizerPlusLoadComments() { return new self( - "You have to enable opcache.load_comments=1 or zend_optimizerplus.load_comments=1." + 'You have to enable opcache.load_comments=1 or zend_optimizerplus.load_comments=1.' ); } } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php index 6c579775f..1f538ee53 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php @@ -1,122 +1,57 @@ . - */ namespace Doctrine\Common\Annotations; use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation; use Doctrine\Common\Annotations\Annotation\Target; use ReflectionClass; +use ReflectionFunction; use ReflectionMethod; use ReflectionProperty; +use function array_merge; +use function class_exists; +use function extension_loaded; +use function ini_get; + /** * A reader for docblock annotations. - * - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author Johannes M. Schmitt */ class AnnotationReader implements Reader { /** * Global map for imports. * - * @var array + * @var array */ - private static $globalImports = array( - 'ignoreannotation' => 'Doctrine\Common\Annotations\Annotation\IgnoreAnnotation', - ); + private static $globalImports = [ + 'ignoreannotation' => Annotation\IgnoreAnnotation::class, + ]; /** * A list with annotations that are not causing exceptions when not resolved to an annotation class. * * The names are case sensitive. * - * @var array + * @var array */ - private static $globalIgnoredNames = array( - // Annotation tags - 'Annotation' => true, 'Attribute' => true, 'Attributes' => true, - /* Can we enable this? 'Enum' => true, */ - 'Required' => true, - 'Target' => true, - // Widely used tags (but not existent in phpdoc) - 'fix' => true , 'fixme' => true, - 'override' => true, - // PHPDocumentor 1 tags - 'abstract'=> true, 'access'=> true, - 'code' => true, - 'deprec'=> true, - 'endcode' => true, 'exception'=> true, - 'final'=> true, - 'ingroup' => true, 'inheritdoc'=> true, 'inheritDoc'=> true, - 'magic' => true, - 'name'=> true, - 'toc' => true, 'tutorial'=> true, - 'private' => true, - 'static'=> true, 'staticvar'=> true, 'staticVar'=> true, - 'throw' => true, - // PHPDocumentor 2 tags. - 'api' => true, 'author'=> true, - 'category'=> true, 'copyright'=> true, - 'deprecated'=> true, - 'example'=> true, - 'filesource'=> true, - 'global'=> true, - 'ignore'=> true, /* Can we enable this? 'index' => true, */ 'internal'=> true, - 'license'=> true, 'link'=> true, - 'method' => true, - 'package'=> true, 'param'=> true, 'property' => true, 'property-read' => true, 'property-write' => true, - 'return'=> true, - 'see'=> true, 'since'=> true, 'source' => true, 'subpackage'=> true, - 'throws'=> true, 'todo'=> true, 'TODO'=> true, - 'usedby'=> true, 'uses' => true, - 'var'=> true, 'version'=> true, - // PHPUnit tags - 'codeCoverageIgnore' => true, 'codeCoverageIgnoreStart' => true, 'codeCoverageIgnoreEnd' => true, - // PHPCheckStyle - 'SuppressWarnings' => true, - // PHPStorm - 'noinspection' => true, - // PEAR - 'package_version' => true, - // PlantUML - 'startuml' => true, 'enduml' => true, - ); + private static $globalIgnoredNames = ImplicitlyIgnoredAnnotationNames::LIST; /** * A list with annotations that are not causing exceptions when not resolved to an annotation class. * * The names are case sensitive. * - * @var array + * @var array */ - private static $globalIgnoredNamespaces = array(); + private static $globalIgnoredNamespaces = []; /** * Add a new annotation to the globally ignored annotation names with regard to exception handling. * * @param string $name */ - static public function addGlobalIgnoredName($name) + public static function addGlobalIgnoredName($name) { self::$globalIgnoredNames[$name] = true; } @@ -126,7 +61,7 @@ class AnnotationReader implements Reader * * @param string $namespace */ - static public function addGlobalIgnoredNamespace($namespace) + public static function addGlobalIgnoredNamespace($namespace) { self::$globalIgnoredNamespaces[$namespace] = true; } @@ -134,75 +69,68 @@ class AnnotationReader implements Reader /** * Annotations parser. * - * @var \Doctrine\Common\Annotations\DocParser + * @var DocParser */ private $parser; /** * Annotations parser used to collect parsing metadata. * - * @var \Doctrine\Common\Annotations\DocParser + * @var DocParser */ private $preParser; /** * PHP parser used to collect imports. * - * @var \Doctrine\Common\Annotations\PhpParser + * @var PhpParser */ private $phpParser; /** * In-memory cache mechanism to store imported annotations per class. * - * @var array + * @psalm-var array<'class'|'function', array>> */ - private $imports = array(); + private $imports = []; /** * In-memory cache mechanism to store ignored annotations per class. * - * @var array + * @psalm-var array<'class'|'function', array>> */ - private $ignoredAnnotationNames = array(); + private $ignoredAnnotationNames = []; /** - * Constructor. - * * Initializes a new AnnotationReader. * - * @param DocParser $parser + * @throws AnnotationException */ - public function __construct(DocParser $parser = null) + public function __construct(?DocParser $parser = null) { - if (extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.save_comments') === "0" || ini_get('opcache.save_comments') === "0")) { + if ( + extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.save_comments') === '0' || + ini_get('opcache.save_comments') === '0') + ) { throw AnnotationException::optimizerPlusSaveComments(); } - if (extension_loaded('Zend OPcache') && ini_get('opcache.save_comments') == 0) { + if (extension_loaded('Zend OPcache') && ini_get('opcache.save_comments') === 0) { throw AnnotationException::optimizerPlusSaveComments(); } - if (PHP_VERSION_ID < 70000) { - if (extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.load_comments') === "0" || ini_get('opcache.load_comments') === "0")) { - throw AnnotationException::optimizerPlusLoadComments(); - } - - if (extension_loaded('Zend OPcache') && ini_get('opcache.load_comments') == 0) { - throw AnnotationException::optimizerPlusLoadComments(); - } - } - - AnnotationRegistry::registerFile(__DIR__ . '/Annotation/IgnoreAnnotation.php'); + // Make sure that the IgnoreAnnotation annotation is loaded + class_exists(IgnoreAnnotation::class); $this->parser = $parser ?: new DocParser(); - $this->preParser = new DocParser; + $this->preParser = new DocParser(); $this->preParser->setImports(self::$globalImports); $this->preParser->setIgnoreNotImportedAnnotations(true); + $this->preParser->setIgnoredAnnotationNames(self::$globalIgnoredNames); - $this->phpParser = new PhpParser; + $this->phpParser = new PhpParser(); } /** @@ -211,7 +139,7 @@ class AnnotationReader implements Reader public function getClassAnnotations(ReflectionClass $class) { $this->parser->setTarget(Target::TARGET_CLASS); - $this->parser->setImports($this->getClassImports($class)); + $this->parser->setImports($this->getImports($class)); $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class)); $this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces); @@ -240,7 +168,7 @@ class AnnotationReader implements Reader public function getPropertyAnnotations(ReflectionProperty $property) { $class = $property->getDeclaringClass(); - $context = 'property ' . $class->getName() . "::\$" . $property->getName(); + $context = 'property ' . $class->getName() . '::$' . $property->getName(); $this->parser->setTarget(Target::TARGET_PROPERTY); $this->parser->setImports($this->getPropertyImports($property)); @@ -299,66 +227,103 @@ class AnnotationReader implements Reader } /** - * Returns the ignored annotations for the given class. + * Gets the annotations applied to a function. * - * @param \ReflectionClass $class - * - * @return array + * @phpstan-return list An array of Annotations. */ - private function getIgnoredAnnotationNames(ReflectionClass $class) + public function getFunctionAnnotations(ReflectionFunction $function): array { - $name = $class->getName(); - if (isset($this->ignoredAnnotationNames[$name])) { - return $this->ignoredAnnotationNames[$name]; - } + $context = 'function ' . $function->getName(); - $this->collectParsingMetadata($class); + $this->parser->setTarget(Target::TARGET_FUNCTION); + $this->parser->setImports($this->getImports($function)); + $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($function)); + $this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces); - return $this->ignoredAnnotationNames[$name]; + return $this->parser->parse($function->getDocComment(), $context); } /** - * Retrieves imports. + * Gets a function annotation. * - * @param \ReflectionClass $class - * - * @return array + * @return object|null The Annotation or NULL, if the requested annotation does not exist. */ - private function getClassImports(ReflectionClass $class) + public function getFunctionAnnotation(ReflectionFunction $function, string $annotationName) { - $name = $class->getName(); - if (isset($this->imports[$name])) { - return $this->imports[$name]; + $annotations = $this->getFunctionAnnotations($function); + + foreach ($annotations as $annotation) { + if ($annotation instanceof $annotationName) { + return $annotation; + } } - $this->collectParsingMetadata($class); + return null; + } - return $this->imports[$name]; + /** + * Returns the ignored annotations for the given class or function. + * + * @param ReflectionClass|ReflectionFunction $reflection + * + * @return array + */ + private function getIgnoredAnnotationNames($reflection): array + { + $type = $reflection instanceof ReflectionClass ? 'class' : 'function'; + $name = $reflection->getName(); + + if (isset($this->ignoredAnnotationNames[$type][$name])) { + return $this->ignoredAnnotationNames[$type][$name]; + } + + $this->collectParsingMetadata($reflection); + + return $this->ignoredAnnotationNames[$type][$name]; + } + + /** + * Retrieves imports for a class or a function. + * + * @param ReflectionClass|ReflectionFunction $reflection + * + * @return array + */ + private function getImports($reflection): array + { + $type = $reflection instanceof ReflectionClass ? 'class' : 'function'; + $name = $reflection->getName(); + + if (isset($this->imports[$type][$name])) { + return $this->imports[$type][$name]; + } + + $this->collectParsingMetadata($reflection); + + return $this->imports[$type][$name]; } /** * Retrieves imports for methods. * - * @param \ReflectionMethod $method - * - * @return array + * @return array */ private function getMethodImports(ReflectionMethod $method) { - $class = $method->getDeclaringClass(); - $classImports = $this->getClassImports($class); - if (!method_exists($class, 'getTraits')) { - return $classImports; - } + $class = $method->getDeclaringClass(); + $classImports = $this->getImports($class); - $traitImports = array(); + $traitImports = []; foreach ($class->getTraits() as $trait) { - if ($trait->hasMethod($method->getName()) - && $trait->getFileName() === $method->getFileName() + if ( + ! $trait->hasMethod($method->getName()) + || $trait->getFileName() !== $method->getFileName() ) { - $traitImports = array_merge($traitImports, $this->phpParser->parseClass($trait)); + continue; } + + $traitImports = array_merge($traitImports, $this->phpParser->parseUseStatements($trait)); } return array_merge($classImports, $traitImports); @@ -367,55 +332,58 @@ class AnnotationReader implements Reader /** * Retrieves imports for properties. * - * @param \ReflectionProperty $property - * - * @return array + * @return array */ private function getPropertyImports(ReflectionProperty $property) { - $class = $property->getDeclaringClass(); - $classImports = $this->getClassImports($class); - if (!method_exists($class, 'getTraits')) { - return $classImports; - } + $class = $property->getDeclaringClass(); + $classImports = $this->getImports($class); - $traitImports = array(); + $traitImports = []; foreach ($class->getTraits() as $trait) { - if ($trait->hasProperty($property->getName())) { - $traitImports = array_merge($traitImports, $this->phpParser->parseClass($trait)); + if (! $trait->hasProperty($property->getName())) { + continue; } + + $traitImports = array_merge($traitImports, $this->phpParser->parseUseStatements($trait)); } return array_merge($classImports, $traitImports); } /** - * Collects parsing metadata for a given class. + * Collects parsing metadata for a given class or function. * - * @param \ReflectionClass $class + * @param ReflectionClass|ReflectionFunction $reflection */ - private function collectParsingMetadata(ReflectionClass $class) + private function collectParsingMetadata($reflection): void { + $type = $reflection instanceof ReflectionClass ? 'class' : 'function'; + $name = $reflection->getName(); + $ignoredAnnotationNames = self::$globalIgnoredNames; - $annotations = $this->preParser->parse($class->getDocComment(), 'class ' . $class->name); + $annotations = $this->preParser->parse($reflection->getDocComment(), $type . ' ' . $name); foreach ($annotations as $annotation) { - if ($annotation instanceof IgnoreAnnotation) { - foreach ($annotation->names AS $annot) { - $ignoredAnnotationNames[$annot] = true; - } + if (! ($annotation instanceof IgnoreAnnotation)) { + continue; + } + + foreach ($annotation->names as $annot) { + $ignoredAnnotationNames[$annot] = true; } } - $name = $class->getName(); - - $this->imports[$name] = array_merge( + $this->imports[$type][$name] = array_merge( self::$globalImports, - $this->phpParser->parseClass($class), - array('__NAMESPACE__' => $class->getNamespaceName()) + $this->phpParser->parseUseStatements($reflection), + [ + '__NAMESPACE__' => $reflection->getNamespaceName(), + 'self' => $name, + ] ); - $this->ignoredAnnotationNames[$name] = $ignoredAnnotationNames; + $this->ignoredAnnotationNames[$type][$name] = $ignoredAnnotationNames; } } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php index 13ceb6348..259d497dd 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php @@ -1,27 +1,18 @@ . - */ namespace Doctrine\Common\Annotations; -/** - * AnnotationRegistry. - */ +use function array_key_exists; +use function array_merge; +use function class_exists; +use function in_array; +use function is_file; +use function str_replace; +use function stream_resolve_include_path; +use function strpos; + +use const DIRECTORY_SEPARATOR; + final class AnnotationRegistry { /** @@ -32,35 +23,49 @@ final class AnnotationRegistry * * This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own. * - * @var array + * @var string[][]|string[]|null[] */ - static private $autoloadNamespaces = array(); + private static $autoloadNamespaces = []; /** * A map of autoloader callables. * - * @var array + * @var callable[] */ - static private $loaders = array(); + private static $loaders = []; /** - * @return void + * An array of classes which cannot be found + * + * @var null[] indexed by class name */ - static public function reset() + private static $failedToAutoload = []; + + /** + * Whenever registerFile() was used. Disables use of standard autoloader. + * + * @var bool + */ + private static $registerFileUsed = false; + + public static function reset(): void { - self::$autoloadNamespaces = array(); - self::$loaders = array(); + self::$autoloadNamespaces = []; + self::$loaders = []; + self::$failedToAutoload = []; + self::$registerFileUsed = false; } /** * Registers file. * - * @param string $file - * - * @return void + * @deprecated This method is deprecated and will be removed in + * doctrine/annotations 2.0. Annotations will be autoloaded in 2.0. */ - static public function registerFile($file) + public static function registerFile(string $file): void { + self::$registerFileUsed = true; + require_once $file; } @@ -69,12 +74,12 @@ final class AnnotationRegistry * * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm. * - * @param string $namespace - * @param string|array|null $dirs + * @deprecated This method is deprecated and will be removed in + * doctrine/annotations 2.0. Annotations will be autoloaded in 2.0. * - * @return void + * @phpstan-param string|list|null $dirs */ - static public function registerAutoloadNamespace($namespace, $dirs = null) + public static function registerAutoloadNamespace(string $namespace, $dirs = null): void { self::$autoloadNamespaces[$namespace] = $dirs; } @@ -84,11 +89,12 @@ final class AnnotationRegistry * * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm. * - * @param array $namespaces + * @deprecated This method is deprecated and will be removed in + * doctrine/annotations 2.0. Annotations will be autoloaded in 2.0. * - * @return void + * @param string[][]|string[]|null[] $namespaces indexed by namespace name */ - static public function registerAutoloadNamespaces(array $namespaces) + public static function registerAutoloadNamespaces(array $namespaces): void { self::$autoloadNamespaces = array_merge(self::$autoloadNamespaces, $namespaces); } @@ -99,53 +105,86 @@ final class AnnotationRegistry * NOTE: These class loaders HAVE to be silent when a class was not found! * IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class. * - * @param callable $callable - * - * @return void - * - * @throws \InvalidArgumentException + * @deprecated This method is deprecated and will be removed in + * doctrine/annotations 2.0. Annotations will be autoloaded in 2.0. */ - static public function registerLoader($callable) + public static function registerLoader(callable $callable): void { - if (!is_callable($callable)) { - throw new \InvalidArgumentException("A callable is expected in AnnotationRegistry::registerLoader()."); + // Reset our static cache now that we have a new loader to work with + self::$failedToAutoload = []; + self::$loaders[] = $callable; + } + + /** + * Registers an autoloading callable for annotations, if it is not already registered + * + * @deprecated This method is deprecated and will be removed in + * doctrine/annotations 2.0. Annotations will be autoloaded in 2.0. + */ + public static function registerUniqueLoader(callable $callable): void + { + if (in_array($callable, self::$loaders, true)) { + return; } - self::$loaders[] = $callable; + + self::registerLoader($callable); } /** * Autoloads an annotation class silently. - * - * @param string $class - * - * @return boolean */ - static public function loadAnnotationClass($class) + public static function loadAnnotationClass(string $class): bool { - foreach (self::$autoloadNamespaces AS $namespace => $dirs) { - if (strpos($class, $namespace) === 0) { - $file = str_replace("\\", DIRECTORY_SEPARATOR, $class) . ".php"; - if ($dirs === null) { - if ($path = stream_resolve_include_path($file)) { - require $path; + if (class_exists($class, false)) { + return true; + } + + if (array_key_exists($class, self::$failedToAutoload)) { + return false; + } + + foreach (self::$autoloadNamespaces as $namespace => $dirs) { + if (strpos($class, $namespace) !== 0) { + continue; + } + + $file = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php'; + + if ($dirs === null) { + $path = stream_resolve_include_path($file); + if ($path) { + require $path; + + return true; + } + } else { + foreach ((array) $dirs as $dir) { + if (is_file($dir . DIRECTORY_SEPARATOR . $file)) { + require $dir . DIRECTORY_SEPARATOR . $file; + return true; } - } else { - foreach((array)$dirs AS $dir) { - if (is_file($dir . DIRECTORY_SEPARATOR . $file)) { - require $dir . DIRECTORY_SEPARATOR . $file; - return true; - } - } } } } - foreach (self::$loaders AS $loader) { - if (call_user_func($loader, $class) === true) { + foreach (self::$loaders as $loader) { + if ($loader($class) === true) { return true; } } + + if ( + self::$loaders === [] && + self::$autoloadNamespaces === [] && + self::$registerFileUsed === false && + class_exists($class) + ) { + return true; + } + + self::$failedToAutoload[$class] = null; + return false; } } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php index 751c1b1b7..91fbad0c6 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php @@ -1,67 +1,47 @@ . - */ namespace Doctrine\Common\Annotations; use Doctrine\Common\Cache\Cache; use ReflectionClass; +use ReflectionMethod; +use ReflectionProperty; + +use function array_map; +use function array_merge; +use function assert; +use function filemtime; +use function max; +use function time; /** * A cache aware annotation reader. - * - * @author Johannes M. Schmitt - * @author Benjamin Eberlei */ final class CachedReader implements Reader { - /** - * @var Reader - */ + /** @var Reader */ private $delegate; - /** - * @var Cache - */ + /** @var Cache */ private $cache; - /** - * @var boolean - */ + /** @var bool */ private $debug; - /** - * @var array - */ - private $loadedAnnotations = array(); + /** @var array> */ + private $loadedAnnotations = []; + + /** @var int[] */ + private $loadedFilemtimes = []; /** - * Constructor. - * - * @param Reader $reader - * @param Cache $cache - * @param bool $debug + * @param bool $debug */ public function __construct(Reader $reader, Cache $cache, $debug = false) { $this->delegate = $reader; - $this->cache = $cache; - $this->debug = (boolean) $debug; + $this->cache = $cache; + $this->debug = (bool) $debug; } /** @@ -75,7 +55,8 @@ final class CachedReader implements Reader return $this->loadedAnnotations[$cacheKey]; } - if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) { + $annots = $this->fetchFromCache($cacheKey, $class); + if ($annots === false) { $annots = $this->delegate->getClassAnnotations($class); $this->saveToCache($cacheKey, $annots); } @@ -100,16 +81,17 @@ final class CachedReader implements Reader /** * {@inheritDoc} */ - public function getPropertyAnnotations(\ReflectionProperty $property) + public function getPropertyAnnotations(ReflectionProperty $property) { - $class = $property->getDeclaringClass(); - $cacheKey = $class->getName().'$'.$property->getName(); + $class = $property->getDeclaringClass(); + $cacheKey = $class->getName() . '$' . $property->getName(); if (isset($this->loadedAnnotations[$cacheKey])) { return $this->loadedAnnotations[$cacheKey]; } - if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) { + $annots = $this->fetchFromCache($cacheKey, $class); + if ($annots === false) { $annots = $this->delegate->getPropertyAnnotations($property); $this->saveToCache($cacheKey, $annots); } @@ -120,7 +102,7 @@ final class CachedReader implements Reader /** * {@inheritDoc} */ - public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) + public function getPropertyAnnotation(ReflectionProperty $property, $annotationName) { foreach ($this->getPropertyAnnotations($property) as $annot) { if ($annot instanceof $annotationName) { @@ -134,16 +116,17 @@ final class CachedReader implements Reader /** * {@inheritDoc} */ - public function getMethodAnnotations(\ReflectionMethod $method) + public function getMethodAnnotations(ReflectionMethod $method) { - $class = $method->getDeclaringClass(); - $cacheKey = $class->getName().'#'.$method->getName(); + $class = $method->getDeclaringClass(); + $cacheKey = $class->getName() . '#' . $method->getName(); if (isset($this->loadedAnnotations[$cacheKey])) { return $this->loadedAnnotations[$cacheKey]; } - if (false === ($annots = $this->fetchFromCache($cacheKey, $class))) { + $annots = $this->fetchFromCache($cacheKey, $class); + if ($annots === false) { $annots = $this->delegate->getMethodAnnotations($method); $this->saveToCache($cacheKey, $annots); } @@ -154,7 +137,7 @@ final class CachedReader implements Reader /** * {@inheritDoc} */ - public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) + public function getMethodAnnotation(ReflectionMethod $method, $annotationName) { foreach ($this->getMethodAnnotations($method) as $annot) { if ($annot instanceof $annotationName) { @@ -172,21 +155,22 @@ final class CachedReader implements Reader */ public function clearLoadedAnnotations() { - $this->loadedAnnotations = array(); + $this->loadedAnnotations = []; + $this->loadedFilemtimes = []; } /** * Fetches a value from the cache. * - * @param string $cacheKey The cache key. - * @param ReflectionClass $class The related class. + * @param string $cacheKey The cache key. * * @return mixed The cached value or false when the value is not in cache. */ private function fetchFromCache($cacheKey, ReflectionClass $class) { - if (($data = $this->cache->fetch($cacheKey)) !== false) { - if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) { + $data = $this->cache->fetch($cacheKey); + if ($data !== false) { + if (! $this->debug || $this->isCacheFresh($cacheKey, $class)) { return $data; } } @@ -205,58 +189,76 @@ final class CachedReader implements Reader private function saveToCache($cacheKey, $value) { $this->cache->save($cacheKey, $value); - if ($this->debug) { - $this->cache->save('[C]'.$cacheKey, time()); + if (! $this->debug) { + return; } + + $this->cache->save('[C]' . $cacheKey, time()); } /** * Checks if the cache is fresh. * - * @param string $cacheKey - * @param ReflectionClass $class + * @param string $cacheKey * - * @return boolean + * @return bool */ private function isCacheFresh($cacheKey, ReflectionClass $class) { - if (null === $lastModification = $this->getLastModification($class)) { + $lastModification = $this->getLastModification($class); + if ($lastModification === 0) { return true; } - return $this->cache->fetch('[C]'.$cacheKey) >= $lastModification; + return $this->cache->fetch('[C]' . $cacheKey) >= $lastModification; } /** * Returns the time the class was last modified, testing traits and parents - * - * @param ReflectionClass $class - * @return int */ - private function getLastModification(ReflectionClass $class) + private function getLastModification(ReflectionClass $class): int { $filename = $class->getFileName(); - $parent = $class->getParentClass(); - return max(array_merge( + if (isset($this->loadedFilemtimes[$filename])) { + return $this->loadedFilemtimes[$filename]; + } + + $parent = $class->getParentClass(); + + $lastModification = max(array_merge( [$filename ? filemtime($filename) : 0], - array_map([$this, 'getTraitLastModificationTime'], $class->getTraits()), - array_map([$this, 'getLastModification'], $class->getInterfaces()), + array_map(function (ReflectionClass $reflectionTrait): int { + return $this->getTraitLastModificationTime($reflectionTrait); + }, $class->getTraits()), + array_map(function (ReflectionClass $class): int { + return $this->getLastModification($class); + }, $class->getInterfaces()), $parent ? [$this->getLastModification($parent)] : [] )); + + assert($lastModification !== false); + + return $this->loadedFilemtimes[$filename] = $lastModification; } - /** - * @param ReflectionClass $reflectionTrait - * @return int - */ - private function getTraitLastModificationTime(ReflectionClass $reflectionTrait) + private function getTraitLastModificationTime(ReflectionClass $reflectionTrait): int { $fileName = $reflectionTrait->getFileName(); - return max(array_merge( + if (isset($this->loadedFilemtimes[$fileName])) { + return $this->loadedFilemtimes[$fileName]; + } + + $lastModificationTime = max(array_merge( [$fileName ? filemtime($fileName) : 0], - array_map([$this, 'getTraitLastModificationTime'], $reflectionTrait->getTraits()) + array_map(function (ReflectionClass $reflectionTrait): int { + return $this->getTraitLastModificationTime($reflectionTrait); + }, $reflectionTrait->getTraits()) )); + + assert($lastModificationTime !== false); + + return $this->loadedFilemtimes[$fileName] = $lastModificationTime; } } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocLexer.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocLexer.php index d864540e0..f6567c512 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocLexer.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocLexer.php @@ -1,61 +1,46 @@ . - */ namespace Doctrine\Common\Annotations; use Doctrine\Common\Lexer\AbstractLexer; +use function ctype_alpha; +use function is_numeric; +use function str_replace; +use function stripos; +use function strlen; +use function strpos; +use function strtolower; +use function substr; + /** * Simple lexer for docblock annotations. - * - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author Johannes M. Schmitt */ final class DocLexer extends AbstractLexer { - const T_NONE = 1; - const T_INTEGER = 2; - const T_STRING = 3; - const T_FLOAT = 4; + public const T_NONE = 1; + public const T_INTEGER = 2; + public const T_STRING = 3; + public const T_FLOAT = 4; // All tokens that are also identifiers should be >= 100 - const T_IDENTIFIER = 100; - const T_AT = 101; - const T_CLOSE_CURLY_BRACES = 102; - const T_CLOSE_PARENTHESIS = 103; - const T_COMMA = 104; - const T_EQUALS = 105; - const T_FALSE = 106; - const T_NAMESPACE_SEPARATOR = 107; - const T_OPEN_CURLY_BRACES = 108; - const T_OPEN_PARENTHESIS = 109; - const T_TRUE = 110; - const T_NULL = 111; - const T_COLON = 112; + public const T_IDENTIFIER = 100; + public const T_AT = 101; + public const T_CLOSE_CURLY_BRACES = 102; + public const T_CLOSE_PARENTHESIS = 103; + public const T_COMMA = 104; + public const T_EQUALS = 105; + public const T_FALSE = 106; + public const T_NAMESPACE_SEPARATOR = 107; + public const T_OPEN_CURLY_BRACES = 108; + public const T_OPEN_PARENTHESIS = 109; + public const T_TRUE = 110; + public const T_NULL = 111; + public const T_COLON = 112; + public const T_MINUS = 113; - /** - * @var array - */ - protected $noCase = array( + /** @var array */ + protected $noCase = [ '@' => self::T_AT, ',' => self::T_COMMA, '(' => self::T_OPEN_PARENTHESIS, @@ -64,28 +49,38 @@ final class DocLexer extends AbstractLexer '}' => self::T_CLOSE_CURLY_BRACES, '=' => self::T_EQUALS, ':' => self::T_COLON, - '\\' => self::T_NAMESPACE_SEPARATOR - ); + '-' => self::T_MINUS, + '\\' => self::T_NAMESPACE_SEPARATOR, + ]; - /** - * @var array - */ - protected $withCase = array( + /** @var array */ + protected $withCase = [ 'true' => self::T_TRUE, 'false' => self::T_FALSE, - 'null' => self::T_NULL - ); + 'null' => self::T_NULL, + ]; + + /** + * Whether the next token starts immediately, or if there were + * non-captured symbols before that + */ + public function nextTokenIsAdjacent(): bool + { + return $this->token === null + || ($this->lookahead !== null + && ($this->lookahead['position'] - $this->token['position']) === strlen($this->token['value'])); + } /** * {@inheritdoc} */ protected function getCatchablePatterns() { - return array( + return [ '[a-z_\\\][a-z0-9_\:\\\]*[a-z_][a-z0-9_]*', '(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?', '"(?:""|[^"])*+"', - ); + ]; } /** @@ -93,7 +88,7 @@ final class DocLexer extends AbstractLexer */ protected function getNonCatchablePatterns() { - return array('\s+', '\*+', '(.)'); + return ['\s+', '\*+', '(.)']; } /** @@ -125,7 +120,7 @@ final class DocLexer extends AbstractLexer // Checking numeric value if (is_numeric($value)) { - return (strpos($value, '.') !== false || stripos($value, 'e') !== false) + return strpos($value, '.') !== false || stripos($value, 'e') !== false ? self::T_FLOAT : self::T_INTEGER; } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php index eb7a457f5..ae530c50f 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php @@ -1,81 +1,93 @@ . - */ namespace Doctrine\Common\Annotations; use Doctrine\Common\Annotations\Annotation\Attribute; -use ReflectionClass; -use Doctrine\Common\Annotations\Annotation\Enum; -use Doctrine\Common\Annotations\Annotation\Target; use Doctrine\Common\Annotations\Annotation\Attributes; +use Doctrine\Common\Annotations\Annotation\Enum; +use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor; +use Doctrine\Common\Annotations\Annotation\Target; +use ReflectionClass; +use ReflectionException; +use ReflectionProperty; +use RuntimeException; +use stdClass; + +use function array_keys; +use function array_map; +use function array_pop; +use function array_values; +use function class_exists; +use function constant; +use function count; +use function defined; +use function explode; +use function gettype; +use function implode; +use function in_array; +use function interface_exists; +use function is_array; +use function is_object; +use function json_encode; +use function ltrim; +use function preg_match; +use function reset; +use function rtrim; +use function sprintf; +use function stripos; +use function strlen; +use function strpos; +use function strrpos; +use function strtolower; +use function substr; +use function trim; + +use const PHP_VERSION_ID; /** * A parser for docblock annotations. * * It is strongly discouraged to change the default annotation parsing process. - * - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author Johannes M. Schmitt - * @author Fabio B. Silva */ final class DocParser { /** * An array of all valid tokens for a class name. * - * @var array + * @phpstan-var list */ - private static $classIdentifiers = array( + private static $classIdentifiers = [ DocLexer::T_IDENTIFIER, DocLexer::T_TRUE, DocLexer::T_FALSE, - DocLexer::T_NULL - ); + DocLexer::T_NULL, + ]; /** * The lexer. * - * @var \Doctrine\Common\Annotations\DocLexer + * @var DocLexer */ private $lexer; /** * Current target context. * - * @var integer + * @var int */ private $target; /** * Doc parser used to collect annotation target. * - * @var \Doctrine\Common\Annotations\DocParser + * @var DocParser */ private static $metadataParser; /** * Flag to control if the current annotation is nested or not. * - * @var boolean + * @var bool */ private $isNestedAnnotation = false; @@ -83,22 +95,22 @@ final class DocParser * Hashmap containing all use-statements that are to be used when parsing * the given doc block. * - * @var array + * @var array */ - private $imports = array(); + private $imports = []; /** * This hashmap is used internally to cache results of class_exists() * look-ups. * - * @var array + * @var array */ - private $classExists = array(); + private $classExists = []; /** * Whether annotations that have not been imported should be ignored. * - * @var boolean + * @var bool */ private $ignoreNotImportedAnnotations = false; @@ -107,17 +119,16 @@ final class DocParser * * @var string[] */ - private $namespaces = array(); + private $namespaces = []; /** * A list with annotations that are not causing exceptions when not resolved to an annotation class. * * The names must be the raw names as used in the class, not the fully qualified - * class names. * * @var bool[] indexed by annotation name */ - private $ignoredAnnotationNames = array(); + private $ignoredAnnotationNames = []; /** * A list with annotations in namespaced format @@ -125,123 +136,131 @@ final class DocParser * * @var bool[] indexed by namespace name */ - private $ignoredAnnotationNamespaces = array(); + private $ignoredAnnotationNamespaces = []; - /** - * @var string - */ + /** @var string */ private $context = ''; /** * Hash-map for caching annotation metadata. * - * @var array + * @var array */ - private static $annotationMetadata = array( - 'Doctrine\Common\Annotations\Annotation\Target' => array( - 'is_annotation' => true, - 'has_constructor' => true, - 'properties' => array(), - 'targets_literal' => 'ANNOTATION_CLASS', - 'targets' => Target::TARGET_CLASS, - 'default_property' => 'value', - 'attribute_types' => array( - 'value' => array( - 'required' => false, - 'type' =>'array', - 'array_type'=>'string', - 'value' =>'array' - ) - ), - ), - 'Doctrine\Common\Annotations\Annotation\Attribute' => array( - 'is_annotation' => true, - 'has_constructor' => false, - 'targets_literal' => 'ANNOTATION_ANNOTATION', - 'targets' => Target::TARGET_ANNOTATION, - 'default_property' => 'name', - 'properties' => array( + private static $annotationMetadata = [ + Annotation\Target::class => [ + 'is_annotation' => true, + 'has_constructor' => true, + 'has_named_argument_constructor' => false, + 'properties' => [], + 'targets_literal' => 'ANNOTATION_CLASS', + 'targets' => Target::TARGET_CLASS, + 'default_property' => 'value', + 'attribute_types' => [ + 'value' => [ + 'required' => false, + 'type' => 'array', + 'array_type' => 'string', + 'value' => 'array', + ], + ], + ], + Annotation\Attribute::class => [ + 'is_annotation' => true, + 'has_constructor' => false, + 'has_named_argument_constructor' => false, + 'targets_literal' => 'ANNOTATION_ANNOTATION', + 'targets' => Target::TARGET_ANNOTATION, + 'default_property' => 'name', + 'properties' => [ 'name' => 'name', 'type' => 'type', - 'required' => 'required' - ), - 'attribute_types' => array( - 'value' => array( + 'required' => 'required', + ], + 'attribute_types' => [ + 'value' => [ 'required' => true, - 'type' =>'string', - 'value' =>'string' - ), - 'type' => array( - 'required' =>true, - 'type' =>'string', - 'value' =>'string' - ), - 'required' => array( - 'required' =>false, - 'type' =>'boolean', - 'value' =>'boolean' - ) - ), - ), - 'Doctrine\Common\Annotations\Annotation\Attributes' => array( - 'is_annotation' => true, - 'has_constructor' => false, - 'targets_literal' => 'ANNOTATION_CLASS', - 'targets' => Target::TARGET_CLASS, - 'default_property' => 'value', - 'properties' => array( - 'value' => 'value' - ), - 'attribute_types' => array( - 'value' => array( - 'type' =>'array', - 'required' =>true, - 'array_type'=>'Doctrine\Common\Annotations\Annotation\Attribute', - 'value' =>'array' - ) - ), - ), - 'Doctrine\Common\Annotations\Annotation\Enum' => array( - 'is_annotation' => true, - 'has_constructor' => true, - 'targets_literal' => 'ANNOTATION_PROPERTY', - 'targets' => Target::TARGET_PROPERTY, - 'default_property' => 'value', - 'properties' => array( - 'value' => 'value' - ), - 'attribute_types' => array( - 'value' => array( + 'type' => 'string', + 'value' => 'string', + ], + 'type' => [ + 'required' => true, + 'type' => 'string', + 'value' => 'string', + ], + 'required' => [ + 'required' => false, + 'type' => 'boolean', + 'value' => 'boolean', + ], + ], + ], + Annotation\Attributes::class => [ + 'is_annotation' => true, + 'has_constructor' => false, + 'has_named_argument_constructor' => false, + 'targets_literal' => 'ANNOTATION_CLASS', + 'targets' => Target::TARGET_CLASS, + 'default_property' => 'value', + 'properties' => ['value' => 'value'], + 'attribute_types' => [ + 'value' => [ 'type' => 'array', 'required' => true, - ), - 'literal' => array( + 'array_type' => Annotation\Attribute::class, + 'value' => 'array<' . Annotation\Attribute::class . '>', + ], + ], + ], + Annotation\Enum::class => [ + 'is_annotation' => true, + 'has_constructor' => true, + 'has_named_argument_constructor' => false, + 'targets_literal' => 'ANNOTATION_PROPERTY', + 'targets' => Target::TARGET_PROPERTY, + 'default_property' => 'value', + 'properties' => ['value' => 'value'], + 'attribute_types' => [ + 'value' => [ + 'type' => 'array', + 'required' => true, + ], + 'literal' => [ 'type' => 'array', 'required' => false, - ), - ), - ), - ); + ], + ], + ], + Annotation\NamedArgumentConstructor::class => [ + 'is_annotation' => true, + 'has_constructor' => false, + 'has_named_argument_constructor' => false, + 'targets_literal' => 'ANNOTATION_CLASS', + 'targets' => Target::TARGET_CLASS, + 'default_property' => null, + 'properties' => [], + 'attribute_types' => [], + ], + ]; /** * Hash-map for handle types declaration. * - * @var array + * @var array */ - private static $typeMap = array( + private static $typeMap = [ 'float' => 'double', 'bool' => 'boolean', // allow uppercase Boolean in honor of George Boole 'Boolean' => 'boolean', 'int' => 'integer', - ); + ]; /** * Constructs a new DocParser. */ public function __construct() { - $this->lexer = new DocLexer; + $this->lexer = new DocLexer(); } /** @@ -274,13 +293,13 @@ final class DocParser /** * Sets ignore on not-imported annotations. * - * @param boolean $bool + * @param bool $bool * * @return void */ public function setIgnoreNotImportedAnnotations($bool) { - $this->ignoreNotImportedAnnotations = (boolean) $bool; + $this->ignoreNotImportedAnnotations = (bool) $bool; } /** @@ -290,12 +309,12 @@ final class DocParser * * @return void * - * @throws \RuntimeException + * @throws RuntimeException */ public function addNamespace($namespace) { if ($this->imports) { - throw new \RuntimeException('You must either use addNamespace(), or setImports(), but not both.'); + throw new RuntimeException('You must either use addNamespace(), or setImports(), but not both.'); } $this->namespaces[] = $namespace; @@ -304,16 +323,16 @@ final class DocParser /** * Sets the imports. * - * @param array $imports + * @param array $imports * * @return void * - * @throws \RuntimeException + * @throws RuntimeException */ public function setImports(array $imports) { if ($this->namespaces) { - throw new \RuntimeException('You must either use addNamespace(), or setImports(), but not both.'); + throw new RuntimeException('You must either use addNamespace(), or setImports(), but not both.'); } $this->imports = $imports; @@ -322,7 +341,7 @@ final class DocParser /** * Sets current target context as bitmask. * - * @param integer $target + * @param int $target * * @return void */ @@ -337,13 +356,16 @@ final class DocParser * @param string $input The docblock string to parse. * @param string $context The parsing context. * - * @return array Array of annotations. If no annotations are found, an empty array is returned. + * @throws AnnotationException + * @throws ReflectionException + * + * @phpstan-return list Array of annotations. If no annotations are found, an empty array is returned. */ public function parse($input, $context = '') { $pos = $this->findInitialTokenPosition($input); if ($pos === null) { - return array(); + return []; } $this->context = $context; @@ -358,10 +380,8 @@ final class DocParser * Finds the first valid annotation * * @param string $input The docblock string to parse - * - * @return int|null */ - private function findInitialTokenPosition($input) + private function findInitialTokenPosition($input): ?int { $pos = 0; @@ -384,14 +404,16 @@ final class DocParser * Attempts to match the given token with the current lookahead token. * If they match, updates the lookahead token; otherwise raises a syntax error. * - * @param integer $token Type of token. + * @param int $token Type of token. * - * @return boolean True if tokens match; false otherwise. + * @return bool True if tokens match; false otherwise. + * + * @throws AnnotationException */ - private function match($token) + private function match(int $token): bool { - if ( ! $this->lexer->isNextToken($token) ) { - $this->syntaxError($this->lexer->getLiteral($token)); + if (! $this->lexer->isNextToken($token)) { + throw $this->syntaxError($this->lexer->getLiteral($token)); } return $this->lexer->moveNext(); @@ -403,14 +425,14 @@ final class DocParser * If any of them matches, this method updates the lookahead token; otherwise * a syntax error is raised. * - * @param array $tokens + * @throws AnnotationException * - * @return boolean + * @phpstan-param list $tokens */ - private function matchAny(array $tokens) + private function matchAny(array $tokens): bool { - if ( ! $this->lexer->isNextTokenAny($tokens)) { - $this->syntaxError(implode(' or ', array_map(array($this->lexer, 'getLiteral'), $tokens))); + if (! $this->lexer->isNextTokenAny($tokens)) { + throw $this->syntaxError(implode(' or ', array_map([$this->lexer, 'getLiteral'], $tokens))); } return $this->lexer->moveNext(); @@ -419,21 +441,17 @@ final class DocParser /** * Generates a new syntax error. * - * @param string $expected Expected string. - * @param array|null $token Optional token. - * - * @return void - * - * @throws AnnotationException + * @param string $expected Expected string. + * @param mixed[]|null $token Optional token. */ - private function syntaxError($expected, $token = null) + private function syntaxError(string $expected, ?array $token = null): AnnotationException { if ($token === null) { $token = $this->lexer->lookahead; } $message = sprintf('Expected %s, got ', $expected); - $message .= ($this->lexer->lookahead === null) + $message .= $this->lexer->lookahead === null ? 'end of string' : sprintf("'%s' at position %s", $token['value'], $token['position']); @@ -443,18 +461,16 @@ final class DocParser $message .= '.'; - throw AnnotationException::syntaxError($message); + return AnnotationException::syntaxError($message); } /** * Attempts to check if a class exists or not. This never goes through the PHP autoloading mechanism * but uses the {@link AnnotationRegistry} to load classes. * - * @param string $fqcn - * - * @return boolean + * @param class-string $fqcn */ - private function classExists($fqcn) + private function classExists(string $fqcn): bool { if (isset($this->classExists[$fqcn])) { return $this->classExists[$fqcn]; @@ -472,44 +488,53 @@ final class DocParser /** * Collects parsing metadata for a given annotation class * - * @param string $name The annotation name + * @param class-string $name The annotation name * - * @return void + * @throws AnnotationException + * @throws ReflectionException */ - private function collectAnnotationMetadata($name) + private function collectAnnotationMetadata(string $name): void { if (self::$metadataParser === null) { self::$metadataParser = new self(); self::$metadataParser->setIgnoreNotImportedAnnotations(true); self::$metadataParser->setIgnoredAnnotationNames($this->ignoredAnnotationNames); - self::$metadataParser->setImports(array( - 'enum' => 'Doctrine\Common\Annotations\Annotation\Enum', - 'target' => 'Doctrine\Common\Annotations\Annotation\Target', - 'attribute' => 'Doctrine\Common\Annotations\Annotation\Attribute', - 'attributes' => 'Doctrine\Common\Annotations\Annotation\Attributes' - )); + self::$metadataParser->setImports([ + 'enum' => Enum::class, + 'target' => Target::class, + 'attribute' => Attribute::class, + 'attributes' => Attributes::class, + 'namedargumentconstructor' => NamedArgumentConstructor::class, + ]); - AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Enum.php'); - AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Target.php'); - AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attribute.php'); - AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attributes.php'); + // Make sure that annotations from metadata are loaded + class_exists(Enum::class); + class_exists(Target::class); + class_exists(Attribute::class); + class_exists(Attributes::class); + class_exists(NamedArgumentConstructor::class); } - $class = new \ReflectionClass($name); + $class = new ReflectionClass($name); $docComment = $class->getDocComment(); // Sets default values for annotation metadata - $metadata = array( + $constructor = $class->getConstructor(); + $metadata = [ 'default_property' => null, - 'has_constructor' => (null !== $constructor = $class->getConstructor()) && $constructor->getNumberOfParameters() > 0, - 'properties' => array(), - 'property_types' => array(), - 'attribute_types' => array(), + 'has_constructor' => $constructor !== null && $constructor->getNumberOfParameters() > 0, + 'constructor_args' => [], + 'properties' => [], + 'property_types' => [], + 'attribute_types' => [], 'targets_literal' => null, 'targets' => Target::TARGET_ALL, - 'is_annotation' => false !== strpos($docComment, '@Annotation'), - ); + 'is_annotation' => strpos($docComment, '@Annotation') !== false, + ]; + + $metadata['has_named_argument_constructor'] = $metadata['has_constructor'] + && $class->implementsInterface(NamedArgumentConstructorAnnotation::class); // verify that the class is really meant to be an annotation if ($metadata['is_annotation']) { @@ -523,54 +548,75 @@ final class DocParser continue; } - if ($annotation instanceof Attributes) { - foreach ($annotation->value as $attribute) { - $this->collectAttributeTypeMetadata($metadata, $attribute); + if ($annotation instanceof NamedArgumentConstructor) { + $metadata['has_named_argument_constructor'] = $metadata['has_constructor']; + if ($metadata['has_named_argument_constructor']) { + // choose the first argument as the default property + $metadata['default_property'] = $constructor->getParameters()[0]->getName(); } } + + if (! ($annotation instanceof Attributes)) { + continue; + } + + foreach ($annotation->value as $attribute) { + $this->collectAttributeTypeMetadata($metadata, $attribute); + } } // if not has a constructor will inject values into public properties - if (false === $metadata['has_constructor']) { + if ($metadata['has_constructor'] === false) { // collect all public properties - foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { + foreach ($class->getProperties(ReflectionProperty::IS_PUBLIC) as $property) { $metadata['properties'][$property->name] = $property->name; - if (false === ($propertyComment = $property->getDocComment())) { + $propertyComment = $property->getDocComment(); + if ($propertyComment === false) { continue; } $attribute = new Attribute(); - $attribute->required = (false !== strpos($propertyComment, '@Required')); + $attribute->required = (strpos($propertyComment, '@Required') !== false); $attribute->name = $property->name; - $attribute->type = (false !== strpos($propertyComment, '@var') && preg_match('/@var\s+([^\s]+)/',$propertyComment, $matches)) + $attribute->type = (strpos($propertyComment, '@var') !== false && + preg_match('/@var\s+([^\s]+)/', $propertyComment, $matches)) ? $matches[1] : 'mixed'; $this->collectAttributeTypeMetadata($metadata, $attribute); // checks if the property has @Enum - if (false !== strpos($propertyComment, '@Enum')) { - $context = 'property ' . $class->name . "::\$" . $property->name; + if (strpos($propertyComment, '@Enum') === false) { + continue; + } - self::$metadataParser->setTarget(Target::TARGET_PROPERTY); + $context = 'property ' . $class->name . '::$' . $property->name; - foreach (self::$metadataParser->parse($propertyComment, $context) as $annotation) { - if ( ! $annotation instanceof Enum) { - continue; - } + self::$metadataParser->setTarget(Target::TARGET_PROPERTY); - $metadata['enum'][$property->name]['value'] = $annotation->value; - $metadata['enum'][$property->name]['literal'] = ( ! empty($annotation->literal)) - ? $annotation->literal - : $annotation->value; + foreach (self::$metadataParser->parse($propertyComment, $context) as $annotation) { + if (! $annotation instanceof Enum) { + continue; } + + $metadata['enum'][$property->name]['value'] = $annotation->value; + $metadata['enum'][$property->name]['literal'] = (! empty($annotation->literal)) + ? $annotation->literal + : $annotation->value; } } // choose the first property as default property $metadata['default_property'] = reset($metadata['properties']); + } elseif ($metadata['has_named_argument_constructor']) { + foreach ($constructor->getParameters() as $parameter) { + $metadata['constructor_args'][$parameter->getName()] = [ + 'position' => $parameter->getPosition(), + 'default' => $parameter->isOptional() ? $parameter->getDefaultValue() : null, + ]; + } } } @@ -580,48 +626,43 @@ final class DocParser /** * Collects parsing metadata for a given attribute. * - * @param array $metadata - * @param Attribute $attribute - * - * @return void + * @param mixed[] $metadata */ - private function collectAttributeTypeMetadata(&$metadata, Attribute $attribute) + private function collectAttributeTypeMetadata(array &$metadata, Attribute $attribute): void { // handle internal type declaration - $type = isset(self::$typeMap[$attribute->type]) - ? self::$typeMap[$attribute->type] - : $attribute->type; + $type = self::$typeMap[$attribute->type] ?? $attribute->type; // handle the case if the property type is mixed - if ('mixed' === $type) { + if ($type === 'mixed') { return; } // Evaluate type - switch (true) { + $pos = strpos($type, '<'); + if ($pos !== false) { // Checks if the property has array - case (false !== $pos = strpos($type, '<')): - $arrayType = substr($type, $pos + 1, -1); - $type = 'array'; + $arrayType = substr($type, $pos + 1, -1); + $type = 'array'; - if (isset(self::$typeMap[$arrayType])) { - $arrayType = self::$typeMap[$arrayType]; - } - - $metadata['attribute_types'][$attribute->name]['array_type'] = $arrayType; - break; + if (isset(self::$typeMap[$arrayType])) { + $arrayType = self::$typeMap[$arrayType]; + } + $metadata['attribute_types'][$attribute->name]['array_type'] = $arrayType; + } else { // Checks if the property has type[] - case (false !== $pos = strrpos($type, '[')): - $arrayType = substr($type, 0, $pos); - $type = 'array'; + $pos = strrpos($type, '['); + if ($pos !== false) { + $arrayType = substr($type, 0, $pos); + $type = 'array'; if (isset(self::$typeMap[$arrayType])) { $arrayType = self::$typeMap[$arrayType]; } $metadata['attribute_types'][$attribute->name]['array_type'] = $arrayType; - break; + } } $metadata['attribute_types'][$attribute->name]['type'] = $type; @@ -632,37 +673,55 @@ final class DocParser /** * Annotations ::= Annotation {[ "*" ]* [Annotation]}* * - * @return array + * @throws AnnotationException + * @throws ReflectionException + * + * @phpstan-return list */ - private function Annotations() + private function Annotations(): array { - $annotations = array(); + $annotations = []; - while (null !== $this->lexer->lookahead) { - if (DocLexer::T_AT !== $this->lexer->lookahead['type']) { + while ($this->lexer->lookahead !== null) { + if ($this->lexer->lookahead['type'] !== DocLexer::T_AT) { $this->lexer->moveNext(); continue; } // make sure the @ is preceded by non-catchable pattern - if (null !== $this->lexer->token && $this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value'])) { + if ( + $this->lexer->token !== null && + $this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen( + $this->lexer->token['value'] + ) + ) { $this->lexer->moveNext(); continue; } // make sure the @ is followed by either a namespace separator, or // an identifier token - if ((null === $peek = $this->lexer->glimpse()) - || (DocLexer::T_NAMESPACE_SEPARATOR !== $peek['type'] && !in_array($peek['type'], self::$classIdentifiers, true)) - || $peek['position'] !== $this->lexer->lookahead['position'] + 1) { + $peek = $this->lexer->glimpse(); + if ( + ($peek === null) + || ($peek['type'] !== DocLexer::T_NAMESPACE_SEPARATOR && ! in_array( + $peek['type'], + self::$classIdentifiers, + true + )) + || $peek['position'] !== $this->lexer->lookahead['position'] + 1 + ) { $this->lexer->moveNext(); continue; } $this->isNestedAnnotation = false; - if (false !== $annot = $this->Annotation()) { - $annotations[] = $annot; + $annot = $this->Annotation(); + if ($annot === false) { + continue; } + + $annotations[] = $annot; } return $annotations; @@ -675,9 +734,10 @@ final class DocParser * NameSpacePart ::= identifier | null | false | true * SimpleName ::= identifier | null | false | true * - * @return mixed False if it is not a valid annotation. + * @return object|false False if it is not a valid annotation. * * @throws AnnotationException + * @throws ReflectionException */ private function Annotation() { @@ -686,71 +746,103 @@ final class DocParser // check if we have an annotation $name = $this->Identifier(); + if ( + $this->lexer->isNextToken(DocLexer::T_MINUS) + && $this->lexer->nextTokenIsAdjacent() + ) { + // Annotations with dashes, such as "@foo-" or "@foo-bar", are to be discarded + return false; + } + // only process names which are not fully qualified, yet // fully qualified names must start with a \ $originalName = $name; - if ('\\' !== $name[0]) { - $pos = strpos($name, '\\'); - $alias = (false === $pos)? $name : substr($name, 0, $pos); - $found = false; + if ($name[0] !== '\\') { + $pos = strpos($name, '\\'); + $alias = ($pos === false) ? $name : substr($name, 0, $pos); + $found = false; $loweredAlias = strtolower($alias); if ($this->namespaces) { foreach ($this->namespaces as $namespace) { - if ($this->classExists($namespace.'\\'.$name)) { - $name = $namespace.'\\'.$name; + if ($this->classExists($namespace . '\\' . $name)) { + $name = $namespace . '\\' . $name; $found = true; break; } } } elseif (isset($this->imports[$loweredAlias])) { - $found = true; - $name = (false !== $pos) - ? $this->imports[$loweredAlias] . substr($name, $pos) - : $this->imports[$loweredAlias]; - } elseif ( ! isset($this->ignoredAnnotationNames[$name]) + $namespace = ltrim($this->imports[$loweredAlias], '\\'); + $name = ($pos !== false) + ? $namespace . substr($name, $pos) + : $namespace; + $found = $this->classExists($name); + } elseif ( + ! isset($this->ignoredAnnotationNames[$name]) && isset($this->imports['__NAMESPACE__']) && $this->classExists($this->imports['__NAMESPACE__'] . '\\' . $name) ) { - $name = $this->imports['__NAMESPACE__'].'\\'.$name; + $name = $this->imports['__NAMESPACE__'] . '\\' . $name; $found = true; } elseif (! isset($this->ignoredAnnotationNames[$name]) && $this->classExists($name)) { $found = true; } - if ( ! $found) { + if (! $found) { if ($this->isIgnoredAnnotation($name)) { return false; } - throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s was never imported. Did you maybe forget to add a "use" statement for this annotation?', $name, $this->context)); + throw AnnotationException::semanticalError(sprintf( + <<<'EXCEPTION' +The annotation "@%s" in %s was never imported. Did you maybe forget to add a "use" statement for this annotation? +EXCEPTION + , + $name, + $this->context + )); } } - $name = ltrim($name,'\\'); + $name = ltrim($name, '\\'); - if ( ! $this->classExists($name)) { - throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s does not exist, or could not be auto-loaded.', $name, $this->context)); + if (! $this->classExists($name)) { + throw AnnotationException::semanticalError(sprintf( + 'The annotation "@%s" in %s does not exist, or could not be auto-loaded.', + $name, + $this->context + )); } // at this point, $name contains the fully qualified class name of the // annotation, and it is also guaranteed that this class exists, and // that it is loaded - // collects the metadata annotation only if there is not yet - if ( ! isset(self::$annotationMetadata[$name])) { + if (! isset(self::$annotationMetadata[$name])) { $this->collectAnnotationMetadata($name); } // verify that the class is really meant to be an annotation and not just any ordinary class if (self::$annotationMetadata[$name]['is_annotation'] === false) { - if ($this->ignoreNotImportedAnnotations || isset($this->ignoredAnnotationNames[$originalName])) { + if ($this->isIgnoredAnnotation($originalName) || $this->isIgnoredAnnotation($name)) { return false; } - throw AnnotationException::semanticalError(sprintf('The class "%s" is not annotated with @Annotation. Are you sure this class can be used as annotation? If so, then you need to add @Annotation to the _class_ doc comment of "%s". If it is indeed no annotation, then you need to add @IgnoreAnnotation("%s") to the _class_ doc comment of %s.', $name, $name, $originalName, $this->context)); + throw AnnotationException::semanticalError(sprintf( + <<<'EXCEPTION' +The class "%s" is not annotated with @Annotation. +Are you sure this class can be used as annotation? +If so, then you need to add @Annotation to the _class_ doc comment of "%s". +If it is indeed no annotation, then you need to add @IgnoreAnnotation("%s") to the _class_ doc comment of %s. +EXCEPTION + , + $name, + $name, + $originalName, + $this->context + )); } //if target is nested annotation @@ -760,36 +852,57 @@ final class DocParser $this->isNestedAnnotation = true; //if annotation does not support current target - if (0 === (self::$annotationMetadata[$name]['targets'] & $target) && $target) { + if ((self::$annotationMetadata[$name]['targets'] & $target) === 0 && $target) { throw AnnotationException::semanticalError( - sprintf('Annotation @%s is not allowed to be declared on %s. You may only use this annotation on these code elements: %s.', - $originalName, $this->context, self::$annotationMetadata[$name]['targets_literal']) + sprintf( + <<<'EXCEPTION' +Annotation @%s is not allowed to be declared on %s. You may only use this annotation on these code elements: %s. +EXCEPTION + , + $originalName, + $this->context, + self::$annotationMetadata[$name]['targets_literal'] + ) ); } - $values = $this->MethodCall(); + $arguments = $this->MethodCall(); + $values = $this->resolvePositionalValues($arguments, $name); if (isset(self::$annotationMetadata[$name]['enum'])) { // checks all declared attributes foreach (self::$annotationMetadata[$name]['enum'] as $property => $enum) { // checks if the attribute is a valid enumerator if (isset($values[$property]) && ! in_array($values[$property], $enum['value'])) { - throw AnnotationException::enumeratorError($property, $name, $this->context, $enum['literal'], $values[$property]); + throw AnnotationException::enumeratorError( + $property, + $name, + $this->context, + $enum['literal'], + $values[$property] + ); } } } // checks all declared attributes foreach (self::$annotationMetadata[$name]['attribute_types'] as $property => $type) { - if ($property === self::$annotationMetadata[$name]['default_property'] - && !isset($values[$property]) && isset($values['value'])) { + if ( + $property === self::$annotationMetadata[$name]['default_property'] + && ! isset($values[$property]) && isset($values['value']) + ) { $property = 'value'; } // handle a not given attribute or null value - if (!isset($values[$property])) { + if (! isset($values[$property])) { if ($type['required']) { - throw AnnotationException::requiredError($property, $originalName, $this->context, 'a(n) '.$type['value']); + throw AnnotationException::requiredError( + $property, + $originalName, + $this->context, + 'a(n) ' . $type['value'] + ); } continue; @@ -797,23 +910,67 @@ final class DocParser if ($type['type'] === 'array') { // handle the case of a single value - if ( ! is_array($values[$property])) { - $values[$property] = array($values[$property]); + if (! is_array($values[$property])) { + $values[$property] = [$values[$property]]; } // checks if the attribute has array type declaration, such as "array" if (isset($type['array_type'])) { foreach ($values[$property] as $item) { - if (gettype($item) !== $type['array_type'] && !$item instanceof $type['array_type']) { - throw AnnotationException::attributeTypeError($property, $originalName, $this->context, 'either a(n) '.$type['array_type'].', or an array of '.$type['array_type'].'s', $item); + if (gettype($item) !== $type['array_type'] && ! $item instanceof $type['array_type']) { + throw AnnotationException::attributeTypeError( + $property, + $originalName, + $this->context, + 'either a(n) ' . $type['array_type'] . ', or an array of ' . $type['array_type'] . 's', + $item + ); } } } - } elseif (gettype($values[$property]) !== $type['type'] && !$values[$property] instanceof $type['type']) { - throw AnnotationException::attributeTypeError($property, $originalName, $this->context, 'a(n) '.$type['value'], $values[$property]); + } elseif (gettype($values[$property]) !== $type['type'] && ! $values[$property] instanceof $type['type']) { + throw AnnotationException::attributeTypeError( + $property, + $originalName, + $this->context, + 'a(n) ' . $type['value'], + $values[$property] + ); } } + if (self::$annotationMetadata[$name]['has_named_argument_constructor']) { + if (PHP_VERSION_ID >= 80000) { + return new $name(...$values); + } + + $positionalValues = []; + foreach (self::$annotationMetadata[$name]['constructor_args'] as $property => $parameter) { + $positionalValues[$parameter['position']] = $parameter['default']; + } + + foreach ($values as $property => $value) { + if (! isset(self::$annotationMetadata[$name]['constructor_args'][$property])) { + throw AnnotationException::creationError(sprintf( + <<<'EXCEPTION' +The annotation @%s declared on %s does not have a property named "%s" +that can be set through its named arguments constructor. +Available named arguments: %s +EXCEPTION + , + $originalName, + $this->context, + $property, + implode(', ', array_keys(self::$annotationMetadata[$name]['constructor_args'])) + )); + } + + $positionalValues[self::$annotationMetadata[$name]['constructor_args'][$property]['position']] = $value; + } + + return new $name(...$positionalValues); + } + // check if the annotation expects values via the constructor, // or directly injected into public properties if (self::$annotationMetadata[$name]['has_constructor'] === true) { @@ -823,14 +980,30 @@ final class DocParser $instance = new $name(); foreach ($values as $property => $value) { - if (!isset(self::$annotationMetadata[$name]['properties'][$property])) { - if ('value' !== $property) { - throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not have a property named "%s". Available properties: %s', $originalName, $this->context, $property, implode(', ', self::$annotationMetadata[$name]['properties']))); + if (! isset(self::$annotationMetadata[$name]['properties'][$property])) { + if ($property !== 'value') { + throw AnnotationException::creationError(sprintf( + <<<'EXCEPTION' +The annotation @%s declared on %s does not have a property named "%s". +Available properties: %s +EXCEPTION + , + $originalName, + $this->context, + $property, + implode(', ', self::$annotationMetadata[$name]['properties']) + )); } // handle the case if the property has no annotations - if ( ! $property = self::$annotationMetadata[$name]['default_property']) { - throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not accept any values, but got %s.', $originalName, $this->context, json_encode($values))); + $property = self::$annotationMetadata[$name]['default_property']; + if (! $property) { + throw AnnotationException::creationError(sprintf( + 'The annotation @%s declared on %s does not accept any values, but got %s.', + $originalName, + $this->context, + json_encode($values) + )); } } @@ -843,19 +1016,22 @@ final class DocParser /** * MethodCall ::= ["(" [Values] ")"] * - * @return array + * @return mixed[] + * + * @throws AnnotationException + * @throws ReflectionException */ - private function MethodCall() + private function MethodCall(): array { - $values = array(); + $values = []; - if ( ! $this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) { + if (! $this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) { return $values; } $this->match(DocLexer::T_OPEN_PARENTHESIS); - if ( ! $this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) { + if (! $this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) { $values = $this->Values(); } @@ -867,11 +1043,14 @@ final class DocParser /** * Values ::= Array | Value {"," Value}* [","] * - * @return array + * @return mixed[] + * + * @throws AnnotationException + * @throws ReflectionException */ - private function Values() + private function Values(): array { - $values = array($this->Value()); + $values = [$this->Value()]; while ($this->lexer->isNextToken(DocLexer::T_COMMA)) { $this->match(DocLexer::T_COMMA); @@ -883,30 +1062,20 @@ final class DocParser $token = $this->lexer->lookahead; $value = $this->Value(); - if ( ! is_object($value) && ! is_array($value)) { - $this->syntaxError('Value', $token); - } - $values[] = $value; } + $namedArguments = []; + $positionalArguments = []; foreach ($values as $k => $value) { - if (is_object($value) && $value instanceof \stdClass) { - $values[$value->name] = $value->value; - } else if ( ! isset($values['value'])){ - $values['value'] = $value; + if (is_object($value) && $value instanceof stdClass) { + $namedArguments[$value->name] = $value->value; } else { - if ( ! is_array($values['value'])) { - $values['value'] = array($values['value']); - } - - $values['value'][] = $value; + $positionalArguments[$k] = $value; } - - unset($values[$k]); } - return $values; + return ['named_arguments' => $namedArguments, 'positional_arguments' => $positionalArguments]; } /** @@ -920,81 +1089,112 @@ final class DocParser { $identifier = $this->Identifier(); - if ( ! defined($identifier) && false !== strpos($identifier, '::') && '\\' !== $identifier[0]) { - list($className, $const) = explode('::', $identifier); + if (! defined($identifier) && strpos($identifier, '::') !== false && $identifier[0] !== '\\') { + [$className, $const] = explode('::', $identifier); - $pos = strpos($className, '\\'); - $alias = (false === $pos) ? $className : substr($className, 0, $pos); - $found = false; + $pos = strpos($className, '\\'); + $alias = ($pos === false) ? $className : substr($className, 0, $pos); + $found = false; $loweredAlias = strtolower($alias); switch (true) { - case !empty ($this->namespaces): + case ! empty($this->namespaces): foreach ($this->namespaces as $ns) { - if (class_exists($ns.'\\'.$className) || interface_exists($ns.'\\'.$className)) { - $className = $ns.'\\'.$className; - $found = true; - break; + if (class_exists($ns . '\\' . $className) || interface_exists($ns . '\\' . $className)) { + $className = $ns . '\\' . $className; + $found = true; + break; } } + break; case isset($this->imports[$loweredAlias]): $found = true; - $className = (false !== $pos) + $className = ($pos !== false) ? $this->imports[$loweredAlias] . substr($className, $pos) : $this->imports[$loweredAlias]; break; default: - if(isset($this->imports['__NAMESPACE__'])) { + if (isset($this->imports['__NAMESPACE__'])) { $ns = $this->imports['__NAMESPACE__']; - if (class_exists($ns.'\\'.$className) || interface_exists($ns.'\\'.$className)) { - $className = $ns.'\\'.$className; - $found = true; + if (class_exists($ns . '\\' . $className) || interface_exists($ns . '\\' . $className)) { + $className = $ns . '\\' . $className; + $found = true; } } + break; } if ($found) { - $identifier = $className . '::' . $const; + $identifier = $className . '::' . $const; } } - // checks if identifier ends with ::class, \strlen('::class') === 7 - $classPos = stripos($identifier, '::class'); - if ($classPos === strlen($identifier) - 7) { - return substr($identifier, 0, $classPos); + /** + * Checks if identifier ends with ::class and remove the leading backslash if it exists. + */ + if ( + $this->identifierEndsWithClassConstant($identifier) && + ! $this->identifierStartsWithBackslash($identifier) + ) { + return substr($identifier, 0, $this->getClassConstantPositionInIdentifier($identifier)); } - if (!defined($identifier)) { + if ($this->identifierEndsWithClassConstant($identifier) && $this->identifierStartsWithBackslash($identifier)) { + return substr($identifier, 1, $this->getClassConstantPositionInIdentifier($identifier) - 1); + } + + if (! defined($identifier)) { throw AnnotationException::semanticalErrorConstants($identifier, $this->context); } return constant($identifier); } + private function identifierStartsWithBackslash(string $identifier): bool + { + return $identifier[0] === '\\'; + } + + private function identifierEndsWithClassConstant(string $identifier): bool + { + return $this->getClassConstantPositionInIdentifier($identifier) === strlen($identifier) - strlen('::class'); + } + + /** + * @return int|false + */ + private function getClassConstantPositionInIdentifier(string $identifier) + { + return stripos($identifier, '::class'); + } + /** * Identifier ::= string * - * @return string + * @throws AnnotationException */ - private function Identifier() + private function Identifier(): string { // check if we have an annotation - if ( ! $this->lexer->isNextTokenAny(self::$classIdentifiers)) { - $this->syntaxError('namespace separator or identifier'); + if (! $this->lexer->isNextTokenAny(self::$classIdentifiers)) { + throw $this->syntaxError('namespace separator or identifier'); } $this->lexer->moveNext(); $className = $this->lexer->token['value']; - while ($this->lexer->lookahead['position'] === ($this->lexer->token['position'] + strlen($this->lexer->token['value'])) - && $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { - + while ( + $this->lexer->lookahead !== null && + $this->lexer->lookahead['position'] === ($this->lexer->token['position'] + + strlen($this->lexer->token['value'])) && + $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR) + ) { $this->match(DocLexer::T_NAMESPACE_SEPARATOR); $this->matchAny(self::$classIdentifiers); @@ -1008,12 +1208,15 @@ final class DocParser * Value ::= PlainValue | FieldAssignment * * @return mixed + * + * @throws AnnotationException + * @throws ReflectionException */ private function Value() { $peek = $this->lexer->glimpse(); - if (DocLexer::T_EQUALS === $peek['type']) { + if ($peek['type'] === DocLexer::T_EQUALS) { return $this->FieldAssignment(); } @@ -1024,6 +1227,9 @@ final class DocParser * PlainValue ::= integer | string | float | boolean | Array | Annotation * * @return mixed + * + * @throws AnnotationException + * @throws ReflectionException */ private function PlainValue() { @@ -1042,30 +1248,36 @@ final class DocParser switch ($this->lexer->lookahead['type']) { case DocLexer::T_STRING: $this->match(DocLexer::T_STRING); + return $this->lexer->token['value']; case DocLexer::T_INTEGER: $this->match(DocLexer::T_INTEGER); - return (int)$this->lexer->token['value']; + + return (int) $this->lexer->token['value']; case DocLexer::T_FLOAT: $this->match(DocLexer::T_FLOAT); - return (float)$this->lexer->token['value']; + + return (float) $this->lexer->token['value']; case DocLexer::T_TRUE: $this->match(DocLexer::T_TRUE); + return true; case DocLexer::T_FALSE: $this->match(DocLexer::T_FALSE); + return false; case DocLexer::T_NULL: $this->match(DocLexer::T_NULL); + return null; default: - $this->syntaxError('PlainValue'); + throw $this->syntaxError('PlainValue'); } } @@ -1073,16 +1285,17 @@ final class DocParser * FieldAssignment ::= FieldName "=" PlainValue * FieldName ::= identifier * - * @return \stdClass + * @throws AnnotationException + * @throws ReflectionException */ - private function FieldAssignment() + private function FieldAssignment(): stdClass { $this->match(DocLexer::T_IDENTIFIER); $fieldName = $this->lexer->token['value']; $this->match(DocLexer::T_EQUALS); - $item = new \stdClass(); + $item = new stdClass(); $item->name = $fieldName; $item->value = $this->PlainValue(); @@ -1092,11 +1305,14 @@ final class DocParser /** * Array ::= "{" ArrayEntry {"," ArrayEntry}* [","] "}" * - * @return array + * @return mixed[] + * + * @throws AnnotationException + * @throws ReflectionException */ - private function Arrayx() + private function Arrayx(): array { - $array = $values = array(); + $array = $values = []; $this->match(DocLexer::T_OPEN_CURLY_BRACES); @@ -1123,7 +1339,7 @@ final class DocParser $this->match(DocLexer::T_CLOSE_CURLY_BRACES); foreach ($values as $value) { - list ($key, $val) = $value; + [$key, $val] = $value; if ($key !== null) { $array[$key] = $val; @@ -1140,38 +1356,38 @@ final class DocParser * KeyValuePair ::= Key ("=" | ":") PlainValue | Constant * Key ::= string | integer | Constant * - * @return array + * @throws AnnotationException + * @throws ReflectionException + * + * @phpstan-return array{mixed, mixed} */ - private function ArrayEntry() + private function ArrayEntry(): array { $peek = $this->lexer->glimpse(); - if (DocLexer::T_EQUALS === $peek['type'] - || DocLexer::T_COLON === $peek['type']) { - + if ( + $peek['type'] === DocLexer::T_EQUALS + || $peek['type'] === DocLexer::T_COLON + ) { if ($this->lexer->isNextToken(DocLexer::T_IDENTIFIER)) { $key = $this->Constant(); } else { - $this->matchAny(array(DocLexer::T_INTEGER, DocLexer::T_STRING)); + $this->matchAny([DocLexer::T_INTEGER, DocLexer::T_STRING]); $key = $this->lexer->token['value']; } - $this->matchAny(array(DocLexer::T_EQUALS, DocLexer::T_COLON)); + $this->matchAny([DocLexer::T_EQUALS, DocLexer::T_COLON]); - return array($key, $this->PlainValue()); + return [$key, $this->PlainValue()]; } - return array(null, $this->Value()); + return [null, $this->Value()]; } /** * Checks whether the given $name matches any ignored annotation name or namespace - * - * @param string $name - * - * @return bool */ - private function isIgnoredAnnotation($name) + private function isIgnoredAnnotation(string $name): bool { if ($this->ignoreNotImportedAnnotations || isset($this->ignoredAnnotationNames[$name])) { return true; @@ -1180,11 +1396,64 @@ final class DocParser foreach (array_keys($this->ignoredAnnotationNamespaces) as $ignoredAnnotationNamespace) { $ignoredAnnotationNamespace = rtrim($ignoredAnnotationNamespace, '\\') . '\\'; - if (0 === stripos(rtrim($name, '\\') . '\\', $ignoredAnnotationNamespace)) { + if (stripos(rtrim($name, '\\') . '\\', $ignoredAnnotationNamespace) === 0) { return true; } } return false; } + + /** + * Resolve positional arguments (without name) to named ones + * + * @param array $arguments + * + * @return array + */ + private function resolvePositionalValues(array $arguments, string $name): array + { + $positionalArguments = $arguments['positional_arguments'] ?? []; + $values = $arguments['named_arguments'] ?? []; + + if ( + self::$annotationMetadata[$name]['has_named_argument_constructor'] + && self::$annotationMetadata[$name]['default_property'] !== null + ) { + // We must ensure that we don't have positional arguments after named ones + $positions = array_keys($positionalArguments); + $lastPosition = null; + foreach ($positions as $position) { + if ( + ($lastPosition === null && $position !== 0) || + ($lastPosition !== null && $position !== $lastPosition + 1) + ) { + throw $this->syntaxError('Positional arguments after named arguments is not allowed'); + } + + $lastPosition = $position; + } + + foreach (self::$annotationMetadata[$name]['constructor_args'] as $property => $parameter) { + $position = $parameter['position']; + if (isset($values[$property]) || ! isset($positionalArguments[$position])) { + continue; + } + + $values[$property] = $positionalArguments[$position]; + } + } else { + if (count($positionalArguments) > 0 && ! isset($values['value'])) { + if (count($positionalArguments) === 1) { + $value = array_pop($positionalArguments); + } else { + $value = array_values($positionalArguments); + } + + $values['value'] = $value; + } + } + + return $values; + } } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/FileCacheReader.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/FileCacheReader.php index fd2fedee1..e6a7a958b 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/FileCacheReader.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/FileCacheReader.php @@ -1,89 +1,84 @@ . - */ namespace Doctrine\Common\Annotations; +use InvalidArgumentException; +use ReflectionClass; +use ReflectionMethod; +use ReflectionProperty; +use RuntimeException; + +use function chmod; +use function file_put_contents; +use function filemtime; +use function gettype; +use function is_dir; +use function is_file; +use function is_int; +use function is_writable; +use function mkdir; +use function rename; +use function rtrim; +use function serialize; +use function sha1; +use function sprintf; +use function strtr; +use function tempnam; +use function uniqid; +use function unlink; +use function var_export; + /** * File cache reader for annotations. * - * @author Johannes M. Schmitt - * @author Benjamin Eberlei - * * @deprecated the FileCacheReader is deprecated and will be removed * in version 2.0.0 of doctrine/annotations. Please use the * {@see \Doctrine\Common\Annotations\CachedReader} instead. */ class FileCacheReader implements Reader { - /** - * @var Reader - */ + /** @var Reader */ private $reader; - /** - * @var string - */ + /** @var string */ private $dir; - /** - * @var bool - */ + /** @var bool */ private $debug; - /** - * @var array - */ - private $loadedAnnotations = array(); + /** @phpstan-var array> */ + private $loadedAnnotations = []; - /** - * @var array - */ - private $classNameHashes = array(); + /** @var array */ + private $classNameHashes = []; - /** - * @var int - */ + /** @var int */ private $umask; /** - * Constructor. + * @param string $cacheDir + * @param bool $debug + * @param int $umask * - * @param Reader $reader - * @param string $cacheDir - * @param boolean $debug - * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function __construct(Reader $reader, $cacheDir, $debug = false, $umask = 0002) { - if ( ! is_int($umask)) { - throw new \InvalidArgumentException(sprintf( + if (! is_int($umask)) { + throw new InvalidArgumentException(sprintf( 'The parameter umask must be an integer, was: %s', gettype($umask) )); } $this->reader = $reader; - $this->umask = $umask; + $this->umask = $umask; - if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777 & (~$this->umask), true)) { - throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $cacheDir)); + if (! is_dir($cacheDir) && ! @mkdir($cacheDir, 0777 & (~$this->umask), true)) { + throw new InvalidArgumentException(sprintf( + 'The directory "%s" does not exist and could not be created.', + $cacheDir + )); } $this->dir = rtrim($cacheDir, '\\/'); @@ -93,31 +88,37 @@ class FileCacheReader implements Reader /** * {@inheritDoc} */ - public function getClassAnnotations(\ReflectionClass $class) + public function getClassAnnotations(ReflectionClass $class) { - if ( ! isset($this->classNameHashes[$class->name])) { + if (! isset($this->classNameHashes[$class->name])) { $this->classNameHashes[$class->name] = sha1($class->name); } + $key = $this->classNameHashes[$class->name]; if (isset($this->loadedAnnotations[$key])) { return $this->loadedAnnotations[$key]; } - $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php'; - if (!is_file($path)) { + $path = $this->dir . '/' . strtr($key, '\\', '-') . '.cache.php'; + if (! is_file($path)) { $annot = $this->reader->getClassAnnotations($class); $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; } - if ($this->debug - && (false !== $filename = $class->getFileName()) - && filemtime($path) < filemtime($filename)) { + $filename = $class->getFilename(); + if ( + $this->debug + && $filename !== false + && filemtime($path) < filemtime($filename) + ) { @unlink($path); $annot = $this->reader->getClassAnnotations($class); $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; } @@ -127,32 +128,38 @@ class FileCacheReader implements Reader /** * {@inheritDoc} */ - public function getPropertyAnnotations(\ReflectionProperty $property) + public function getPropertyAnnotations(ReflectionProperty $property) { $class = $property->getDeclaringClass(); - if ( ! isset($this->classNameHashes[$class->name])) { + if (! isset($this->classNameHashes[$class->name])) { $this->classNameHashes[$class->name] = sha1($class->name); } - $key = $this->classNameHashes[$class->name].'$'.$property->getName(); + + $key = $this->classNameHashes[$class->name] . '$' . $property->getName(); if (isset($this->loadedAnnotations[$key])) { return $this->loadedAnnotations[$key]; } - $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php'; - if (!is_file($path)) { + $path = $this->dir . '/' . strtr($key, '\\', '-') . '.cache.php'; + if (! is_file($path)) { $annot = $this->reader->getPropertyAnnotations($property); $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; } - if ($this->debug - && (false !== $filename = $class->getFilename()) - && filemtime($path) < filemtime($filename)) { + $filename = $class->getFilename(); + if ( + $this->debug + && $filename !== false + && filemtime($path) < filemtime($filename) + ) { @unlink($path); $annot = $this->reader->getPropertyAnnotations($property); $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; } @@ -162,32 +169,38 @@ class FileCacheReader implements Reader /** * {@inheritDoc} */ - public function getMethodAnnotations(\ReflectionMethod $method) + public function getMethodAnnotations(ReflectionMethod $method) { $class = $method->getDeclaringClass(); - if ( ! isset($this->classNameHashes[$class->name])) { + if (! isset($this->classNameHashes[$class->name])) { $this->classNameHashes[$class->name] = sha1($class->name); } - $key = $this->classNameHashes[$class->name].'#'.$method->getName(); + + $key = $this->classNameHashes[$class->name] . '#' . $method->getName(); if (isset($this->loadedAnnotations[$key])) { return $this->loadedAnnotations[$key]; } - $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php'; - if (!is_file($path)) { + $path = $this->dir . '/' . strtr($key, '\\', '-') . '.cache.php'; + if (! is_file($path)) { $annot = $this->reader->getMethodAnnotations($method); $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; } - if ($this->debug - && (false !== $filename = $class->getFilename()) - && filemtime($path) < filemtime($filename)) { + $filename = $class->getFilename(); + if ( + $this->debug + && $filename !== false + && filemtime($path) < filemtime($filename) + ) { @unlink($path); $annot = $this->reader->getMethodAnnotations($method); $this->saveCacheFile($path, $annot); + return $this->loadedAnnotations[$key] = $annot; } @@ -204,36 +217,48 @@ class FileCacheReader implements Reader */ private function saveCacheFile($path, $data) { - if (!is_writable($this->dir)) { - throw new \InvalidArgumentException(sprintf('The directory "%s" is not writable. Both, the webserver and the console user need access. You can manage access rights for multiple users with "chmod +a". If your system does not support this, check out the acl package.', $this->dir)); + if (! is_writable($this->dir)) { + throw new InvalidArgumentException(sprintf( + <<<'EXCEPTION' +The directory "%s" is not writable. Both the webserver and the console user need access. +You can manage access rights for multiple users with "chmod +a". +If your system does not support this, check out the acl package., +EXCEPTION + , + $this->dir + )); } $tempfile = tempnam($this->dir, uniqid('', true)); - if (false === $tempfile) { - throw new \RuntimeException(sprintf('Unable to create tempfile in directory: %s', $this->dir)); + if ($tempfile === false) { + throw new RuntimeException(sprintf('Unable to create tempfile in directory: %s', $this->dir)); } @chmod($tempfile, 0666 & (~$this->umask)); - $written = file_put_contents($tempfile, 'umask)); - if (false === rename($tempfile, $path)) { + if (rename($tempfile, $path) === false) { @unlink($tempfile); - throw new \RuntimeException(sprintf('Unable to rename %s to %s', $tempfile, $path)); + + throw new RuntimeException(sprintf('Unable to rename %s to %s', $tempfile, $path)); } } /** * {@inheritDoc} */ - public function getClassAnnotation(\ReflectionClass $class, $annotationName) + public function getClassAnnotation(ReflectionClass $class, $annotationName) { $annotations = $this->getClassAnnotations($class); @@ -249,7 +274,7 @@ class FileCacheReader implements Reader /** * {@inheritDoc} */ - public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) + public function getMethodAnnotation(ReflectionMethod $method, $annotationName) { $annotations = $this->getMethodAnnotations($method); @@ -265,7 +290,7 @@ class FileCacheReader implements Reader /** * {@inheritDoc} */ - public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) + public function getPropertyAnnotation(ReflectionProperty $property, $annotationName) { $annotations = $this->getPropertyAnnotations($property); @@ -285,6 +310,6 @@ class FileCacheReader implements Reader */ public function clearLoadedAnnotations() { - $this->loadedAnnotations = array(); + $this->loadedAnnotations = []; } } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/ImplicitlyIgnoredAnnotationNames.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/ImplicitlyIgnoredAnnotationNames.php new file mode 100644 index 000000000..52b929d34 --- /dev/null +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/ImplicitlyIgnoredAnnotationNames.php @@ -0,0 +1,171 @@ + true, + 'Attribute' => true, + 'Attributes' => true, + /* Can we enable this? 'Enum' => true, */ + 'Required' => true, + 'Target' => true, + ]; + + private const WidelyUsedNonStandard = [ + 'fix' => true, + 'fixme' => true, + 'override' => true, + ]; + + private const PhpDocumentor1 = [ + 'abstract' => true, + 'access' => true, + 'code' => true, + 'deprec' => true, + 'endcode' => true, + 'exception' => true, + 'final' => true, + 'ingroup' => true, + 'inheritdoc' => true, + 'inheritDoc' => true, + 'magic' => true, + 'name' => true, + 'private' => true, + 'static' => true, + 'staticvar' => true, + 'staticVar' => true, + 'toc' => true, + 'tutorial' => true, + 'throw' => true, + ]; + + private const PhpDocumentor2 = [ + 'api' => true, + 'author' => true, + 'category' => true, + 'copyright' => true, + 'deprecated' => true, + 'example' => true, + 'filesource' => true, + 'global' => true, + 'ignore' => true, + /* Can we enable this? 'index' => true, */ + 'internal' => true, + 'license' => true, + 'link' => true, + 'method' => true, + 'package' => true, + 'param' => true, + 'property' => true, + 'property-read' => true, + 'property-write' => true, + 'return' => true, + 'see' => true, + 'since' => true, + 'source' => true, + 'subpackage' => true, + 'throws' => true, + 'todo' => true, + 'TODO' => true, + 'usedby' => true, + 'uses' => true, + 'var' => true, + 'version' => true, + ]; + + private const PHPUnit = [ + 'author' => true, + 'after' => true, + 'afterClass' => true, + 'backupGlobals' => true, + 'backupStaticAttributes' => true, + 'before' => true, + 'beforeClass' => true, + 'codeCoverageIgnore' => true, + 'codeCoverageIgnoreStart' => true, + 'codeCoverageIgnoreEnd' => true, + 'covers' => true, + 'coversDefaultClass' => true, + 'coversNothing' => true, + 'dataProvider' => true, + 'depends' => true, + 'doesNotPerformAssertions' => true, + 'expectedException' => true, + 'expectedExceptionCode' => true, + 'expectedExceptionMessage' => true, + 'expectedExceptionMessageRegExp' => true, + 'group' => true, + 'large' => true, + 'medium' => true, + 'preserveGlobalState' => true, + 'requires' => true, + 'runTestsInSeparateProcesses' => true, + 'runInSeparateProcess' => true, + 'small' => true, + 'test' => true, + 'testdox' => true, + 'testWith' => true, + 'ticket' => true, + 'uses' => true, + ]; + + private const PhpCheckStyle = ['SuppressWarnings' => true]; + + private const PhpStorm = ['noinspection' => true]; + + private const PEAR = ['package_version' => true]; + + private const PlainUML = [ + 'startuml' => true, + 'enduml' => true, + ]; + + private const Symfony = ['experimental' => true]; + + private const PhpCodeSniffer = [ + 'codingStandardsIgnoreStart' => true, + 'codingStandardsIgnoreEnd' => true, + ]; + + private const SlevomatCodingStandard = ['phpcsSuppress' => true]; + + private const PhpStan = [ + 'extends' => true, + 'implements' => true, + 'template' => true, + 'use' => true, + ]; + + private const Phan = ['suppress' => true]; + + private const Rector = ['noRector' => true]; + + public const LIST = self::Reserved + + self::WidelyUsedNonStandard + + self::PhpDocumentor1 + + self::PhpDocumentor2 + + self::PHPUnit + + self::PhpCheckStyle + + self::PhpStorm + + self::PEAR + + self::PlainUML + + self::Symfony + + self::SlevomatCodingStandard + + self::PhpCodeSniffer + + self::PhpStan + + self::Phan + + self::Rector; + + private function __construct() + { + } +} diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/IndexedReader.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/IndexedReader.php index bf7fbdcdd..42e70765d 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/IndexedReader.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/IndexedReader.php @@ -1,41 +1,22 @@ . - */ namespace Doctrine\Common\Annotations; +use ReflectionClass; +use ReflectionMethod; +use ReflectionProperty; + +use function call_user_func_array; +use function get_class; + /** * Allows the reader to be used in-place of Doctrine's reader. - * - * @author Johannes M. Schmitt */ class IndexedReader implements Reader { - /** - * @var Reader - */ + /** @var Reader */ private $delegate; - /** - * Constructor. - * - * @param Reader $reader - */ public function __construct(Reader $reader) { $this->delegate = $reader; @@ -44,9 +25,9 @@ class IndexedReader implements Reader /** * {@inheritDoc} */ - public function getClassAnnotations(\ReflectionClass $class) + public function getClassAnnotations(ReflectionClass $class) { - $annotations = array(); + $annotations = []; foreach ($this->delegate->getClassAnnotations($class) as $annot) { $annotations[get_class($annot)] = $annot; } @@ -57,7 +38,7 @@ class IndexedReader implements Reader /** * {@inheritDoc} */ - public function getClassAnnotation(\ReflectionClass $class, $annotation) + public function getClassAnnotation(ReflectionClass $class, $annotation) { return $this->delegate->getClassAnnotation($class, $annotation); } @@ -65,9 +46,9 @@ class IndexedReader implements Reader /** * {@inheritDoc} */ - public function getMethodAnnotations(\ReflectionMethod $method) + public function getMethodAnnotations(ReflectionMethod $method) { - $annotations = array(); + $annotations = []; foreach ($this->delegate->getMethodAnnotations($method) as $annot) { $annotations[get_class($annot)] = $annot; } @@ -78,7 +59,7 @@ class IndexedReader implements Reader /** * {@inheritDoc} */ - public function getMethodAnnotation(\ReflectionMethod $method, $annotation) + public function getMethodAnnotation(ReflectionMethod $method, $annotation) { return $this->delegate->getMethodAnnotation($method, $annotation); } @@ -86,9 +67,9 @@ class IndexedReader implements Reader /** * {@inheritDoc} */ - public function getPropertyAnnotations(\ReflectionProperty $property) + public function getPropertyAnnotations(ReflectionProperty $property) { - $annotations = array(); + $annotations = []; foreach ($this->delegate->getPropertyAnnotations($property) as $annot) { $annotations[get_class($annot)] = $annot; } @@ -99,7 +80,7 @@ class IndexedReader implements Reader /** * {@inheritDoc} */ - public function getPropertyAnnotation(\ReflectionProperty $property, $annotation) + public function getPropertyAnnotation(ReflectionProperty $property, $annotation) { return $this->delegate->getPropertyAnnotation($property, $annotation); } @@ -107,13 +88,13 @@ class IndexedReader implements Reader /** * Proxies all methods to the delegate. * - * @param string $method - * @param array $args + * @param string $method + * @param mixed[] $args * * @return mixed */ public function __call($method, $args) { - return call_user_func_array(array($this->delegate, $method), $args); + return call_user_func_array([$this->delegate, $method], $args); } } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/NamedArgumentConstructorAnnotation.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/NamedArgumentConstructorAnnotation.php new file mode 100644 index 000000000..8af224c0b --- /dev/null +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/NamedArgumentConstructorAnnotation.php @@ -0,0 +1,14 @@ +. - */ namespace Doctrine\Common\Annotations; +use ReflectionClass; +use ReflectionFunction; use SplFileObject; +use function is_file; +use function method_exists; +use function preg_quote; +use function preg_replace; + /** * Parses a file for namespaces/use/class declarations. - * - * @author Fabien Potencier - * @author Christian Kaps */ final class PhpParser { /** * Parses a class. * - * @param \ReflectionClass $class A ReflectionClass object. + * @deprecated use parseUseStatements instead * - * @return array A list with use statements in the form (Alias => FQN). + * @param ReflectionClass $class A ReflectionClass object. + * + * @return array A list with use statements in the form (Alias => FQN). */ - public function parseClass(\ReflectionClass $class) + public function parseClass(ReflectionClass $class) { - if (method_exists($class, 'getUseStatements')) { - return $class->getUseStatements(); + return $this->parseUseStatements($class); + } + + /** + * Parse a class or function for use statements. + * + * @param ReflectionClass|ReflectionFunction $reflection + * + * @psalm-return array a list with use statements in the form (Alias => FQN). + */ + public function parseUseStatements($reflection): array + { + if (method_exists($reflection, 'getUseStatements')) { + return $reflection->getUseStatements(); } - if (false === $filename = $class->getFileName()) { - return array(); + $filename = $reflection->getFileName(); + + if ($filename === false) { + return []; } - $content = $this->getFileContent($filename, $class->getStartLine()); + $content = $this->getFileContent($filename, $reflection->getStartLine()); - if (null === $content) { - return array(); + if ($content === null) { + return []; } - $namespace = preg_quote($class->getNamespaceName()); - $content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content); + $namespace = preg_quote($reflection->getNamespaceName()); + $content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content); $tokenizer = new TokenParser('parseUseStatements($class->getNamespaceName()); - - return $statements; + return $tokenizer->parseUseStatements($reflection->getNamespaceName()); } /** * Gets the content of the file right up to the given line number. * - * @param string $filename The name of the file to load. - * @param integer $lineNumber The number of lines to read from file. + * @param string $filename The name of the file to load. + * @param int $lineNumber The number of lines to read from file. * * @return string|null The content of the file or null if the file does not exist. */ private function getFileContent($filename, $lineNumber) { - if ( ! is_file($filename)) { + if (! is_file($filename)) { return null; } $content = ''; $lineCnt = 0; - $file = new SplFileObject($filename); - while (!$file->eof()) { - if ($lineCnt++ == $lineNumber) { + $file = new SplFileObject($filename); + while (! $file->eof()) { + if ($lineCnt++ === $lineNumber) { break; } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Reader.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Reader.php index 4774f8731..0663ffda0 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Reader.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Reader.php @@ -1,89 +1,80 @@ . - */ namespace Doctrine\Common\Annotations; +use ReflectionClass; +use ReflectionMethod; +use ReflectionProperty; + /** * Interface for annotation readers. - * - * @author Johannes M. Schmitt */ interface Reader { /** * Gets the annotations applied to a class. * - * @param \ReflectionClass $class The ReflectionClass of the class from which - * the class annotations should be read. + * @param ReflectionClass $class The ReflectionClass of the class from which + * the class annotations should be read. * - * @return array An array of Annotations. + * @return array An array of Annotations. */ - function getClassAnnotations(\ReflectionClass $class); + public function getClassAnnotations(ReflectionClass $class); /** * Gets a class annotation. * - * @param \ReflectionClass $class The ReflectionClass of the class from which - * the class annotations should be read. - * @param string $annotationName The name of the annotation. + * @param ReflectionClass $class The ReflectionClass of the class from which + * the class annotations should be read. + * @param class-string $annotationName The name of the annotation. * - * @return object|null The Annotation or NULL, if the requested annotation does not exist. + * @return T|null The Annotation or NULL, if the requested annotation does not exist. + * + * @template T */ - function getClassAnnotation(\ReflectionClass $class, $annotationName); + public function getClassAnnotation(ReflectionClass $class, $annotationName); /** * Gets the annotations applied to a method. * - * @param \ReflectionMethod $method The ReflectionMethod of the method from which - * the annotations should be read. + * @param ReflectionMethod $method The ReflectionMethod of the method from which + * the annotations should be read. * - * @return array An array of Annotations. + * @return array An array of Annotations. */ - function getMethodAnnotations(\ReflectionMethod $method); + public function getMethodAnnotations(ReflectionMethod $method); /** * Gets a method annotation. * - * @param \ReflectionMethod $method The ReflectionMethod to read the annotations from. - * @param string $annotationName The name of the annotation. + * @param ReflectionMethod $method The ReflectionMethod to read the annotations from. + * @param class-string $annotationName The name of the annotation. * - * @return object|null The Annotation or NULL, if the requested annotation does not exist. + * @return T|null The Annotation or NULL, if the requested annotation does not exist. + * + * @template T */ - function getMethodAnnotation(\ReflectionMethod $method, $annotationName); + public function getMethodAnnotation(ReflectionMethod $method, $annotationName); /** * Gets the annotations applied to a property. * - * @param \ReflectionProperty $property The ReflectionProperty of the property - * from which the annotations should be read. + * @param ReflectionProperty $property The ReflectionProperty of the property + * from which the annotations should be read. * - * @return array An array of Annotations. + * @return array An array of Annotations. */ - function getPropertyAnnotations(\ReflectionProperty $property); + public function getPropertyAnnotations(ReflectionProperty $property); /** * Gets a property annotation. * - * @param \ReflectionProperty $property The ReflectionProperty to read the annotations from. - * @param string $annotationName The name of the annotation. + * @param ReflectionProperty $property The ReflectionProperty to read the annotations from. + * @param class-string $annotationName The name of the annotation. * - * @return object|null The Annotation or NULL, if the requested annotation does not exist. + * @return T|null The Annotation or NULL, if the requested annotation does not exist. + * + * @template T */ - function getPropertyAnnotation(\ReflectionProperty $property, $annotationName); + public function getPropertyAnnotation(ReflectionProperty $property, $annotationName); } diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php index d4757eea2..8a78c119d 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php @@ -1,44 +1,25 @@ . - */ namespace Doctrine\Common\Annotations; +use ReflectionClass; +use ReflectionMethod; +use ReflectionProperty; + /** * Simple Annotation Reader. * * This annotation reader is intended to be used in projects where you have * full-control over all annotations that are available. * - * @since 2.2 - * @author Johannes M. Schmitt - * @author Fabio B. Silva + * @deprecated Deprecated in favour of using AnnotationReader */ class SimpleAnnotationReader implements Reader { - /** - * @var DocParser - */ + /** @var DocParser */ private $parser; /** - * Constructor. - * * Initializes a new SimpleAnnotationReader. */ public function __construct() @@ -62,31 +43,37 @@ class SimpleAnnotationReader implements Reader /** * {@inheritDoc} */ - public function getClassAnnotations(\ReflectionClass $class) + public function getClassAnnotations(ReflectionClass $class) { - return $this->parser->parse($class->getDocComment(), 'class '.$class->getName()); + return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName()); } /** * {@inheritDoc} */ - public function getMethodAnnotations(\ReflectionMethod $method) + public function getMethodAnnotations(ReflectionMethod $method) { - return $this->parser->parse($method->getDocComment(), 'method '.$method->getDeclaringClass()->name.'::'.$method->getName().'()'); + return $this->parser->parse( + $method->getDocComment(), + 'method ' . $method->getDeclaringClass()->name . '::' . $method->getName() . '()' + ); } /** * {@inheritDoc} */ - public function getPropertyAnnotations(\ReflectionProperty $property) + public function getPropertyAnnotations(ReflectionProperty $property) { - return $this->parser->parse($property->getDocComment(), 'property '.$property->getDeclaringClass()->name.'::$'.$property->getName()); + return $this->parser->parse( + $property->getDocComment(), + 'property ' . $property->getDeclaringClass()->name . '::$' . $property->getName() + ); } /** * {@inheritDoc} */ - public function getClassAnnotation(\ReflectionClass $class, $annotationName) + public function getClassAnnotation(ReflectionClass $class, $annotationName) { foreach ($this->getClassAnnotations($class) as $annot) { if ($annot instanceof $annotationName) { @@ -100,7 +87,7 @@ class SimpleAnnotationReader implements Reader /** * {@inheritDoc} */ - public function getMethodAnnotation(\ReflectionMethod $method, $annotationName) + public function getMethodAnnotation(ReflectionMethod $method, $annotationName) { foreach ($this->getMethodAnnotations($method) as $annot) { if ($annot instanceof $annotationName) { @@ -114,7 +101,7 @@ class SimpleAnnotationReader implements Reader /** * {@inheritDoc} */ - public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName) + public function getPropertyAnnotation(ReflectionProperty $property, $annotationName) { foreach ($this->getPropertyAnnotations($property) as $annot) { if ($annot instanceof $annotationName) { diff --git a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/TokenParser.php b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/TokenParser.php index bf1b71339..9605fb8dd 100644 --- a/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/TokenParser.php +++ b/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/TokenParser.php @@ -1,36 +1,34 @@ . - */ namespace Doctrine\Common\Annotations; +use function array_merge; +use function count; +use function explode; +use function strtolower; +use function token_get_all; + +use const PHP_VERSION_ID; +use const T_AS; +use const T_COMMENT; +use const T_DOC_COMMENT; +use const T_NAME_FULLY_QUALIFIED; +use const T_NAME_QUALIFIED; +use const T_NAMESPACE; +use const T_NS_SEPARATOR; +use const T_STRING; +use const T_USE; +use const T_WHITESPACE; + /** * Parses a file for namespaces/use/class declarations. - * - * @author Fabien Potencier - * @author Christian Kaps */ class TokenParser { /** * The token list. * - * @var array + * @phpstan-var list */ private $tokens; @@ -70,19 +68,20 @@ class TokenParser /** * Gets the next non whitespace and non comment token. * - * @param boolean $docCommentIsComment If TRUE then a doc comment is considered a comment and skipped. - * If FALSE then only whitespace and normal comments are skipped. + * @param bool $docCommentIsComment If TRUE then a doc comment is considered a comment and skipped. + * If FALSE then only whitespace and normal comments are skipped. * - * @return array|null The token if exists, null otherwise. + * @return mixed[]|string|null The token if exists, null otherwise. */ - public function next($docCommentIsComment = TRUE) + public function next($docCommentIsComment = true) { for ($i = $this->pointer; $i < $this->numTokens; $i++) { $this->pointer++; - if ($this->tokens[$i][0] === T_WHITESPACE || + if ( + $this->tokens[$i][0] === T_WHITESPACE || $this->tokens[$i][0] === T_COMMENT || - ($docCommentIsComment && $this->tokens[$i][0] === T_DOC_COMMENT)) { - + ($docCommentIsComment && $this->tokens[$i][0] === T_DOC_COMMENT) + ) { continue; } @@ -95,38 +94,47 @@ class TokenParser /** * Parses a single use statement. * - * @return array A list with all found class names for a use statement. + * @return array A list with all found class names for a use statement. */ public function parseUseStatement() { - - $groupRoot = ''; - $class = ''; - $alias = ''; - $statements = array(); + $groupRoot = ''; + $class = ''; + $alias = ''; + $statements = []; $explicitAlias = false; while (($token = $this->next())) { - $isNameToken = $token[0] === T_STRING || $token[0] === T_NS_SEPARATOR; - if (!$explicitAlias && $isNameToken) { + if (! $explicitAlias && $token[0] === T_STRING) { $class .= $token[1]; + $alias = $token[1]; + } elseif ($explicitAlias && $token[0] === T_STRING) { $alias = $token[1]; - } else if ($explicitAlias && $isNameToken) { - $alias .= $token[1]; - } else if ($token[0] === T_AS) { + } elseif ( + PHP_VERSION_ID >= 80000 && + ($token[0] === T_NAME_QUALIFIED || $token[0] === T_NAME_FULLY_QUALIFIED) + ) { + $class .= $token[1]; + + $classSplit = explode('\\', $token[1]); + $alias = $classSplit[count($classSplit) - 1]; + } elseif ($token[0] === T_NS_SEPARATOR) { + $class .= '\\'; + $alias = ''; + } elseif ($token[0] === T_AS) { $explicitAlias = true; - $alias = ''; - } else if ($token === ',') { + $alias = ''; + } elseif ($token === ',') { $statements[strtolower($alias)] = $groupRoot . $class; - $class = ''; - $alias = ''; - $explicitAlias = false; - } else if ($token === ';') { + $class = ''; + $alias = ''; + $explicitAlias = false; + } elseif ($token === ';') { $statements[strtolower($alias)] = $groupRoot . $class; break; - } else if ($token === '{' ) { + } elseif ($token === '{') { $groupRoot = $class; - $class = ''; - } else if ($token === '}' ) { + $class = ''; + } elseif ($token === '}') { continue; } else { break; @@ -141,24 +149,25 @@ class TokenParser * * @param string $namespaceName The namespace name of the reflected class. * - * @return array A list with all found use statements. + * @return array A list with all found use statements. */ public function parseUseStatements($namespaceName) { - $statements = array(); + $statements = []; while (($token = $this->next())) { if ($token[0] === T_USE) { $statements = array_merge($statements, $this->parseUseStatement()); continue; } - if ($token[0] !== T_NAMESPACE || $this->parseNamespace() != $namespaceName) { + + if ($token[0] !== T_NAMESPACE || $this->parseNamespace() !== $namespaceName) { continue; } // Get fresh array for new namespace. This is to prevent the parser to collect the use statements // for a previous namespace with the same name. This is the case if a namespace is defined twice // or if a namespace with the same name is commented out. - $statements = array(); + $statements = []; } return $statements; @@ -172,7 +181,12 @@ class TokenParser public function parseNamespace() { $name = ''; - while (($token = $this->next()) && ($token[0] === T_STRING || $token[0] === T_NS_SEPARATOR)) { + while ( + ($token = $this->next()) && ($token[0] === T_STRING || $token[0] === T_NS_SEPARATOR || ( + PHP_VERSION_ID >= 80000 && + ($token[0] === T_NAME_QUALIFIED || $token[0] === T_NAME_FULLY_QUALIFIED) + )) + ) { $name .= $token[1]; } diff --git a/vendor/doctrine/cache/README.md b/vendor/doctrine/cache/README.md index 94f80a30e..c795a0584 100644 --- a/vendor/doctrine/cache/README.md +++ b/vendor/doctrine/cache/README.md @@ -1,14 +1,9 @@ # Doctrine Cache -Master: [![Build Status](https://secure.travis-ci.org/doctrine/cache.png?branch=master)](http://travis-ci.org/doctrine/cache) [![Coverage Status](https://coveralls.io/repos/doctrine/cache/badge.png?branch=master)](https://coveralls.io/r/doctrine/cache?branch=master) +[![Build Status](https://img.shields.io/travis/doctrine/cache/master.svg?style=flat-square)](http://travis-ci.org/doctrine/cache) +[![Code Coverage](https://codecov.io/gh/doctrine/dbal/branch/cache/graph/badge.svg)](https://codecov.io/gh/doctrine/dbal/branch/master) -[![Latest Stable Version](https://poser.pugx.org/doctrine/cache/v/stable.png)](https://packagist.org/packages/doctrine/cache) [![Total Downloads](https://poser.pugx.org/doctrine/cache/downloads.png)](https://packagist.org/packages/doctrine/cache) +[![Latest Stable Version](https://img.shields.io/packagist/v/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache) +[![Total Downloads](https://img.shields.io/packagist/dt/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache) -Cache component extracted from the Doctrine Common project. - -## Changelog - -### v1.2 - -* Added support for MongoDB as Cache Provider -* Fix namespace version reset +Cache component extracted from the Doctrine Common project. [Documentation](https://www.doctrine-project.org/projects/doctrine-cache/en/current/index.html) diff --git a/vendor/doctrine/cache/composer.json b/vendor/doctrine/cache/composer.json index 7ef1727a1..b889aa37d 100644 --- a/vendor/doctrine/cache/composer.json +++ b/vendor/doctrine/cache/composer.json @@ -1,9 +1,19 @@ { "name": "doctrine/cache", "type": "library", - "description": "Caching library offering an object-oriented API for many cache backends", - "keywords": ["cache", "caching"], - "homepage": "http://www.doctrine-project.org", + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "keywords": [ + "php", + "cache", + "caching", + "abstraction", + "redis", + "memcached", + "couchdb", + "xcache", + "apcu" + ], + "homepage": "https://www.doctrine-project.org/projects/cache.html", "license": "MIT", "authors": [ {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, @@ -13,12 +23,17 @@ {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} ], "require": { - "php": "~5.5|~7.0" + "php": "~7.1 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "~4.8|~5.0", - "satooshi/php-coveralls": "~0.6", - "predis/predis": "~1.0" + "alcaeus/mongo-php-adapter": "^1.1", + "mongodb/mongodb": "^1.1", + "phpunit/phpunit": "^7.0", + "predis/predis": "~1.0", + "doctrine/coding-standard": "^6.0" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" }, "conflict": { "doctrine/common": ">2.2,<2.4" @@ -31,7 +46,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "1.9.x-dev" } } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php index 0dfbd6a1d..138d49a53 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php @@ -1,35 +1,22 @@ . - */ namespace Doctrine\Common\Cache; +use const PHP_VERSION_ID; +use function apc_cache_info; +use function apc_clear_cache; +use function apc_delete; +use function apc_exists; +use function apc_fetch; +use function apc_sma_info; +use function apc_store; + /** * APC cache provider. * - * @link www.doctrine-project.org * @deprecated since version 1.6, use ApcuCache instead - * @since 2.0 - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author David Abdemoulaie + * + * @link www.doctrine-project.org */ class ApcCache extends CacheProvider { @@ -102,17 +89,17 @@ class ApcCache extends CacheProvider // @TODO - Temporary fix @see https://github.com/krakjoe/apcu/pull/42 if (PHP_VERSION_ID >= 50500) { - $info['num_hits'] = isset($info['num_hits']) ? $info['num_hits'] : $info['nhits']; - $info['num_misses'] = isset($info['num_misses']) ? $info['num_misses'] : $info['nmisses']; - $info['start_time'] = isset($info['start_time']) ? $info['start_time'] : $info['stime']; + $info['num_hits'] = $info['num_hits'] ?? $info['nhits']; + $info['num_misses'] = $info['num_misses'] ?? $info['nmisses']; + $info['start_time'] = $info['start_time'] ?? $info['stime']; } - return array( + return [ Cache::STATS_HITS => $info['num_hits'], Cache::STATS_MISSES => $info['num_misses'], Cache::STATS_UPTIME => $info['start_time'], Cache::STATS_MEMORY_USAGE => $info['mem_size'], Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'], - ); + ]; } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php index 2a91752ba..a72521361 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php @@ -1,30 +1,20 @@ . - */ namespace Doctrine\Common\Cache; +use function apcu_cache_info; +use function apcu_clear_cache; +use function apcu_delete; +use function apcu_exists; +use function apcu_fetch; +use function apcu_sma_info; +use function apcu_store; +use function count; + /** * APCu cache provider. * * @link www.doctrine-project.org - * @since 1.6 - * @author Kévin Dunglas */ class ApcuCache extends CacheProvider { @@ -61,6 +51,16 @@ class ApcuCache extends CacheProvider return apcu_delete($id) || ! apcu_exists($id); } + /** + * {@inheritdoc} + */ + protected function doDeleteMultiple(array $keys) + { + $result = apcu_delete($keys); + + return $result !== false && count($result) !== count($keys); + } + /** * {@inheritdoc} */ @@ -95,12 +95,12 @@ class ApcuCache extends CacheProvider $info = apcu_cache_info(true); $sma = apcu_sma_info(); - return array( + return [ Cache::STATS_HITS => $info['num_hits'], Cache::STATS_MISSES => $info['num_misses'], Cache::STATS_UPTIME => $info['start_time'], Cache::STATS_MEMORY_USAGE => $info['mem_size'], Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'], - ); + ]; } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php index 6610cc217..1beb7098f 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php @@ -1,55 +1,26 @@ . - */ namespace Doctrine\Common\Cache; +use function time; + /** * Array cache driver. * * @link www.doctrine-project.org - * @since 2.0 - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author David Abdemoulaie */ class ArrayCache extends CacheProvider { - /** - * @var array[] $data each element being a tuple of [$data, $expiration], where the expiration is int|bool - */ + /** @var array[] $data each element being a tuple of [$data, $expiration], where the expiration is int|bool */ private $data = []; - /** - * @var int - */ + /** @var int */ private $hitsCount = 0; - /** - * @var int - */ + /** @var int */ private $missesCount = 0; - /** - * @var int - */ + /** @var int */ private $upTime; /** diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php index 89fe32307..456974427 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php @@ -1,21 +1,4 @@ . - */ namespace Doctrine\Common\Cache; @@ -23,27 +6,20 @@ namespace Doctrine\Common\Cache; * Interface for cache drivers. * * @link www.doctrine-project.org - * @since 2.0 - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author Fabio B. Silva - * @author Kévin Dunglas */ interface Cache { - const STATS_HITS = 'hits'; - const STATS_MISSES = 'misses'; - const STATS_UPTIME = 'uptime'; - const STATS_MEMORY_USAGE = 'memory_usage'; - const STATS_MEMORY_AVAILABLE = 'memory_available'; + public const STATS_HITS = 'hits'; + public const STATS_MISSES = 'misses'; + public const STATS_UPTIME = 'uptime'; + public const STATS_MEMORY_USAGE = 'memory_usage'; + public const STATS_MEMORY_AVAILABLE = 'memory_available'; /** * Only for backward compatibility (may be removed in next major release) * * @deprecated */ - const STATS_MEMORY_AVAILIABLE = 'memory_available'; + public const STATS_MEMORY_AVAILIABLE = 'memory_available'; /** * Fetches an entry from the cache. @@ -108,8 +84,6 @@ interface Cache * - memory_available * Memory allowed to use for storage. * - * @since 2.2 - * * @return array|null An associative array with server's statistics if available, NULL otherwise. */ public function getStats(); diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php index 9f579237a..43d414f3c 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php @@ -1,37 +1,18 @@ . - */ namespace Doctrine\Common\Cache; +use function array_combine; +use function array_key_exists; +use function array_map; +use function sprintf; + /** * Base class for cache provider implementations. - * - * @since 2.2 - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author Fabio B. Silva */ -abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiGetCache, MultiPutCache +abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiOperationCache { - const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]'; + public const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]'; /** * The namespace to prefix all cache ids with. @@ -43,7 +24,7 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M /** * The namespace version. * - * @var integer|null + * @var int|null */ private $namespaceVersion; @@ -84,20 +65,22 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M public function fetchMultiple(array $keys) { if (empty($keys)) { - return array(); + return []; } - + // note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys - $namespacedKeys = array_combine($keys, array_map(array($this, 'getNamespacedId'), $keys)); + $namespacedKeys = array_combine($keys, array_map([$this, 'getNamespacedId'], $keys)); $items = $this->doFetchMultiple($namespacedKeys); - $foundItems = array(); + $foundItems = []; // no internal array function supports this sort of mapping: needs to be iterative // this filters and combines keys in one pass foreach ($namespacedKeys as $requestedKey => $namespacedKey) { - if (isset($items[$namespacedKey]) || array_key_exists($namespacedKey, $items)) { - $foundItems[$requestedKey] = $items[$namespacedKey]; + if (! isset($items[$namespacedKey]) && ! array_key_exists($namespacedKey, $items)) { + continue; } + + $foundItems[$requestedKey] = $items[$namespacedKey]; } return $foundItems; @@ -108,7 +91,7 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M */ public function saveMultiple(array $keysAndValues, $lifetime = 0) { - $namespacedKeysAndValues = array(); + $namespacedKeysAndValues = []; foreach ($keysAndValues as $key => $value) { $namespacedKeysAndValues[$this->getNamespacedId($key)] = $value; } @@ -132,6 +115,14 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M return $this->doSave($this->getNamespacedId($id), $data, $lifeTime); } + /** + * {@inheritdoc} + */ + public function deleteMultiple(array $keys) + { + return $this->doDeleteMultiple(array_map([$this, 'getNamespacedId'], $keys)); + } + /** * {@inheritdoc} */ @@ -180,36 +171,32 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M * * @return string The namespaced id. */ - private function getNamespacedId($id) + private function getNamespacedId(string $id) : string { - $namespaceVersion = $this->getNamespaceVersion(); + $namespaceVersion = $this->getNamespaceVersion(); return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion); } /** * Returns the namespace cache key. - * - * @return string */ - private function getNamespaceCacheKey() + private function getNamespaceCacheKey() : string { return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace); } /** * Returns the namespace version. - * - * @return integer */ - private function getNamespaceVersion() + private function getNamespaceVersion() : int { - if (null !== $this->namespaceVersion) { + if ($this->namespaceVersion !== null) { return $this->namespaceVersion; } - $namespaceCacheKey = $this->getNamespaceCacheKey(); - $this->namespaceVersion = $this->doFetch($namespaceCacheKey) ?: 1; + $namespaceCacheKey = $this->getNamespaceCacheKey(); + $this->namespaceVersion = (int) $this->doFetch($namespaceCacheKey) ?: 1; return $this->namespaceVersion; } @@ -218,16 +205,20 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M * Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it. * * @param array $keys Array of keys to retrieve from cache + * * @return array Array of values retrieved for the given keys. */ protected function doFetchMultiple(array $keys) { - $returnValues = array(); + $returnValues = []; foreach ($keys as $key) { - if (false !== ($item = $this->doFetch($key)) || $this->doContains($key)) { - $returnValues[$key] = $item; + $item = $this->doFetch($key); + if ($item === false && ! $this->doContains($key)) { + continue; } + + $returnValues[$key] = $item; } return $returnValues; @@ -254,9 +245,9 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M /** * Default implementation of doSaveMultiple. Each driver that supports multi-put should override it. * - * @param array $keysAndValues Array of keys and values to save in cache - * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these - * cache entries (0 => infinite lifeTime). + * @param array $keysAndValues Array of keys and values to save in cache + * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these + * cache entries (0 => infinite lifeTime). * * @return bool TRUE if the operation was successful, FALSE if it wasn't. */ @@ -265,9 +256,11 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M $success = true; foreach ($keysAndValues as $key => $value) { - if (!$this->doSave($key, $value, $lifetime)) { - $success = false; + if ($this->doSave($key, $value, $lifetime)) { + continue; } + + $success = false; } return $success; @@ -285,6 +278,28 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M */ abstract protected function doSave($id, $data, $lifeTime = 0); + /** + * Default implementation of doDeleteMultiple. Each driver that supports multi-delete should override it. + * + * @param array $keys Array of keys to delete from cache + * + * @return bool TRUE if the operation was successful, FALSE if it wasn't + */ + protected function doDeleteMultiple(array $keys) + { + $success = true; + + foreach ($keys as $key) { + if ($this->doDelete($key)) { + continue; + } + + $success = false; + } + + return $success; + } + /** * Deletes a cache entry. * @@ -304,8 +319,6 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M /** * Retrieves cached information from the data store. * - * @since 2.2 - * * @return array|null An associative array with server's statistics if available, NULL otherwise. */ abstract protected function doGetStats(); diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php index 96c9b5479..8f85845c7 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php @@ -1,44 +1,36 @@ . - */ namespace Doctrine\Common\Cache; +use Traversable; +use function array_values; +use function count; +use function iterator_to_array; + /** * Cache provider that allows to easily chain multiple cache providers - * - * @author Michaël Gallego */ class ChainCache extends CacheProvider { - /** - * @var CacheProvider[] - */ - private $cacheProviders = array(); + /** @var CacheProvider[] */ + private $cacheProviders = []; + + /** @var int */ + private $defaultLifeTimeForDownstreamCacheProviders = 0; /** - * Constructor - * * @param CacheProvider[] $cacheProviders */ - public function __construct($cacheProviders = array()) + public function __construct($cacheProviders = []) { - $this->cacheProviders = $cacheProviders; + $this->cacheProviders = $cacheProviders instanceof Traversable + ? iterator_to_array($cacheProviders, false) + : array_values($cacheProviders); + } + + public function setDefaultLifeTimeForDownstreamCacheProviders(int $defaultLifeTimeForDownstreamCacheProviders) : void + { + $this->defaultLifeTimeForDownstreamCacheProviders = $defaultLifeTimeForDownstreamCacheProviders; } /** @@ -63,8 +55,8 @@ class ChainCache extends CacheProvider $value = $cacheProvider->doFetch($id); // We populate all the previous cache layers (that are assumed to be faster) - for ($subKey = $key - 1 ; $subKey >= 0 ; $subKey--) { - $this->cacheProviders[$subKey]->doSave($id, $value); + for ($subKey = $key - 1; $subKey >= 0; $subKey--) { + $this->cacheProviders[$subKey]->doSave($id, $value, $this->defaultLifeTimeForDownstreamCacheProviders); } return $value; @@ -74,6 +66,34 @@ class ChainCache extends CacheProvider return false; } + /** + * {@inheritdoc} + */ + protected function doFetchMultiple(array $keys) + { + /** @var CacheProvider[] $traversedProviders */ + $traversedProviders = []; + $keysCount = count($keys); + $fetchedValues = []; + + foreach ($this->cacheProviders as $key => $cacheProvider) { + $fetchedValues = $cacheProvider->doFetchMultiple($keys); + + // We populate all the previous cache layers (that are assumed to be faster) + if (count($fetchedValues) === $keysCount) { + foreach ($traversedProviders as $previousCacheProvider) { + $previousCacheProvider->doSaveMultiple($fetchedValues, $this->defaultLifeTimeForDownstreamCacheProviders); + } + + return $fetchedValues; + } + + $traversedProviders[] = $cacheProvider; + } + + return $fetchedValues; + } + /** * {@inheritDoc} */ @@ -102,6 +122,20 @@ class ChainCache extends CacheProvider return $stored; } + /** + * {@inheritdoc} + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + $stored = true; + + foreach ($this->cacheProviders as $cacheProvider) { + $stored = $cacheProvider->doSaveMultiple($keysAndValues, $lifetime) && $stored; + } + + return $stored; + } + /** * {@inheritDoc} */ @@ -116,6 +150,20 @@ class ChainCache extends CacheProvider return $deleted; } + /** + * {@inheritdoc} + */ + protected function doDeleteMultiple(array $keys) + { + $deleted = true; + + foreach ($this->cacheProviders as $cacheProvider) { + $deleted = $cacheProvider->doDeleteMultiple($keys) && $deleted; + } + + return $deleted; + } + /** * {@inheritDoc} */ @@ -136,7 +184,7 @@ class ChainCache extends CacheProvider protected function doGetStats() { // We return all the stats from all adapters - $stats = array(); + $stats = []; foreach ($this->cacheProviders as $cacheProvider) { $stats[] = $cacheProvider->doGetStats(); diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php index 3a91eaf3a..b94618e46 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php @@ -1,21 +1,4 @@ . - */ namespace Doctrine\Common\Cache; @@ -26,8 +9,6 @@ namespace Doctrine\Common\Cache; * global "flushing", see {@see FlushableCache}. * * @link www.doctrine-project.org - * @since 1.4 - * @author Adirelle */ interface ClearableCache { diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php index c21691df9..2c62c2ea8 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php @@ -1,45 +1,27 @@ . - */ namespace Doctrine\Common\Cache; -use \Couchbase; +use Couchbase; +use function explode; +use function time; /** * Couchbase cache provider. * + * @deprecated Couchbase SDK 1.x is now deprecated. Use \Doctrine\Common\Cache\CouchbaseBucketCache instead. + * https://developer.couchbase.com/documentation/server/current/sdk/php/compatibility-versions-features.html + * * @link www.doctrine-project.org - * @since 2.4 - * @author Michael Nitschinger */ class CouchbaseCache extends CacheProvider { - /** - * @var Couchbase|null - */ + /** @var Couchbase|null */ private $couchbase; /** * Sets the Couchbase instance to use. * - * @param Couchbase $couchbase - * * @return void */ public function setCouchbase(Couchbase $couchbase) @@ -70,7 +52,7 @@ class CouchbaseCache extends CacheProvider */ protected function doContains($id) { - return (null !== $this->couchbase->get($id)); + return $this->couchbase->get($id) !== null; } /** @@ -81,6 +63,7 @@ class CouchbaseCache extends CacheProvider if ($lifeTime > 30 * 24 * 3600) { $lifeTime = time() + $lifeTime; } + return $this->couchbase->set($id, $data, (int) $lifeTime); } @@ -107,15 +90,16 @@ class CouchbaseCache extends CacheProvider { $stats = $this->couchbase->getStats(); $servers = $this->couchbase->getServers(); - $server = explode(":", $servers[0]); - $key = $server[0] . ":" . "11210"; + $server = explode(':', $servers[0]); + $key = $server[0] . ':11210'; $stats = $stats[$key]; - return array( + + return [ Cache::STATS_HITS => $stats['get_hits'], Cache::STATS_MISSES => $stats['get_misses'], Cache::STATS_UPTIME => $stats['uptime'], Cache::STATS_MEMORY_USAGE => $stats['bytes'], Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'], - ); + ]; } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php index b2e0427e5..4b485205c 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php @@ -1,30 +1,39 @@ . - */ namespace Doctrine\Common\Cache; +use FilesystemIterator; +use InvalidArgumentException; +use Iterator; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; +use const DIRECTORY_SEPARATOR; +use const PATHINFO_DIRNAME; +use function bin2hex; +use function chmod; +use function defined; +use function disk_free_space; +use function file_exists; +use function file_put_contents; +use function gettype; +use function hash; +use function is_dir; +use function is_int; +use function is_writable; +use function mkdir; +use function pathinfo; +use function realpath; +use function rename; +use function rmdir; +use function sprintf; +use function strlen; +use function strrpos; +use function substr; +use function tempnam; +use function unlink; + /** * Base file cache driver. - * - * @since 2.3 - * @author Fabio B. Silva - * @author Tobias Schultze */ abstract class FileCache extends CacheProvider { @@ -42,54 +51,44 @@ abstract class FileCache extends CacheProvider */ private $extension; - /** - * @var int - */ + /** @var int */ private $umask; - /** - * @var int - */ + /** @var int */ private $directoryStringLength; - /** - * @var int - */ + /** @var int */ private $extensionStringLength; - /** - * @var bool - */ + /** @var bool */ private $isRunningOnWindows; /** - * Constructor. - * * @param string $directory The cache directory. * @param string $extension The cache file extension. * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function __construct($directory, $extension = '', $umask = 0002) { // YES, this needs to be *before* createPathIfNeeded() - if ( ! is_int($umask)) { - throw new \InvalidArgumentException(sprintf( + if (! is_int($umask)) { + throw new InvalidArgumentException(sprintf( 'The umask parameter is required to be integer, was: %s', gettype($umask) )); } $this->umask = $umask; - if ( ! $this->createPathIfNeeded($directory)) { - throw new \InvalidArgumentException(sprintf( + if (! $this->createPathIfNeeded($directory)) { + throw new InvalidArgumentException(sprintf( 'The directory "%s" does not exist and could not be created.', $directory )); } - if ( ! is_writable($directory)) { - throw new \InvalidArgumentException(sprintf( + if (! is_writable($directory)) { + throw new InvalidArgumentException(sprintf( 'The directory "%s" is not writable.', $directory )); @@ -134,8 +133,7 @@ abstract class FileCache extends CacheProvider $hash = hash('sha256', $id); // This ensures that the filename is unique and that there are no invalid chars in it. - if ( - '' === $id + if ($id === '' || ((strlen($id) * 2 + $this->extensionStringLength) > 255) || ($this->isRunningOnWindows && ($this->directoryStringLength + 4 + strlen($id) * 2 + $this->extensionStringLength) > 258) ) { @@ -195,32 +193,33 @@ abstract class FileCache extends CacheProvider { $usage = 0; foreach ($this->getIterator() as $name => $file) { - if (! $file->isDir() && $this->isFilenameEndingWithExtension($name)) { - $usage += $file->getSize(); + if ($file->isDir() || ! $this->isFilenameEndingWithExtension($name)) { + continue; } + + $usage += $file->getSize(); } $free = disk_free_space($this->directory); - return array( + return [ Cache::STATS_HITS => null, Cache::STATS_MISSES => null, Cache::STATS_UPTIME => null, Cache::STATS_MEMORY_USAGE => $usage, Cache::STATS_MEMORY_AVAILABLE => $free, - ); + ]; } /** * Create path if needed. * - * @param string $path * @return bool TRUE on success or if path already exists, FALSE if path cannot be created. */ - private function createPathIfNeeded($path) + private function createPathIfNeeded(string $path) : bool { - if ( ! is_dir($path)) { - if (false === @mkdir($path, 0777 & (~$this->umask), true) && !is_dir($path)) { + if (! is_dir($path)) { + if (@mkdir($path, 0777 & (~$this->umask), true) === false && ! is_dir($path)) { return false; } } @@ -236,15 +235,15 @@ abstract class FileCache extends CacheProvider * * @return bool TRUE on success, FALSE if path cannot be created, if path is not writable or an any other error. */ - protected function writeFile($filename, $content) + protected function writeFile(string $filename, string $content) : bool { $filepath = pathinfo($filename, PATHINFO_DIRNAME); - if ( ! $this->createPathIfNeeded($filepath)) { + if (! $this->createPathIfNeeded($filepath)) { return false; } - if ( ! is_writable($filepath)) { + if (! is_writable($filepath)) { return false; } @@ -252,6 +251,7 @@ abstract class FileCache extends CacheProvider @chmod($tmpFile, 0666 & (~$this->umask)); if (file_put_contents($tmpFile, $content) !== false) { + @chmod($tmpFile, 0666 & (~$this->umask)); if (@rename($tmpFile, $filename)) { return true; } @@ -262,25 +262,20 @@ abstract class FileCache extends CacheProvider return false; } - /** - * @return \Iterator - */ - private function getIterator() + private function getIterator() : Iterator { - return new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS), - \RecursiveIteratorIterator::CHILD_FIRST + return new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($this->directory, FilesystemIterator::SKIP_DOTS), + RecursiveIteratorIterator::CHILD_FIRST ); } /** * @param string $name The filename - * - * @return bool */ - private function isFilenameEndingWithExtension($name) + private function isFilenameEndingWithExtension(string $name) : bool { - return '' === $this->extension + return $this->extension === '' || strrpos($name, $this->extension) === (strlen($name) - $this->extensionStringLength); } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php index d988294f6..8f34c9cb4 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php @@ -1,33 +1,22 @@ . - */ namespace Doctrine\Common\Cache; +use const PHP_EOL; +use function fclose; +use function fgets; +use function fopen; +use function is_file; +use function serialize; +use function time; +use function unserialize; + /** * Filesystem cache driver. - * - * @since 2.3 - * @author Fabio B. Silva */ class FilesystemCache extends FileCache { - const EXTENSION = '.doctrinecache.data'; + public const EXTENSION = '.doctrinecache.data'; /** * {@inheritdoc} @@ -46,13 +35,14 @@ class FilesystemCache extends FileCache $lifetime = -1; $filename = $this->getFilename($id); - if ( ! is_file($filename)) { + if (! is_file($filename)) { return false; } - $resource = fopen($filename, "r"); + $resource = fopen($filename, 'r'); + $line = fgets($resource); - if (false !== ($line = fgets($resource))) { + if ($line !== false) { $lifetime = (int) $line; } @@ -62,7 +52,7 @@ class FilesystemCache extends FileCache return false; } - while (false !== ($line = fgets($resource))) { + while (($line = fgets($resource)) !== false) { $data .= $line; } @@ -79,13 +69,14 @@ class FilesystemCache extends FileCache $lifetime = -1; $filename = $this->getFilename($id); - if ( ! is_file($filename)) { + if (! is_file($filename)) { return false; } - $resource = fopen($filename, "r"); + $resource = fopen($filename, 'r'); + $line = fgets($resource); - if (false !== ($line = fgets($resource))) { + if ($line !== false) { $lifetime = (int) $line; } @@ -103,8 +94,8 @@ class FilesystemCache extends FileCache $lifeTime = time() + $lifeTime; } - $data = serialize($data); - $filename = $this->getFilename($id); + $data = serialize($data); + $filename = $this->getFilename($id); return $this->writeFile($filename, $lifeTime . PHP_EOL . $data); } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php index 4311d4f59..ee7ce984e 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php @@ -1,21 +1,4 @@ . - */ namespace Doctrine\Common\Cache; @@ -23,8 +6,6 @@ namespace Doctrine\Common\Cache; * Interface for cache that can be flushed. * * @link www.doctrine-project.org - * @since 1.4 - * @author Adirelle */ interface FlushableCache { diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php index 8afaeeacc..42bbd2cea 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php @@ -1,49 +1,25 @@ . - */ namespace Doctrine\Common\Cache; -use \Memcache; +use Memcache; +use function time; /** * Memcache cache provider. * + * @deprecated + * * @link www.doctrine-project.org - * @since 2.0 - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author David Abdemoulaie */ class MemcacheCache extends CacheProvider { - /** - * @var Memcache|null - */ + /** @var Memcache|null */ private $memcache; /** * Sets the memcache instance to use. * - * @param Memcache $memcache - * * @return void */ public function setMemcache(Memcache $memcache) @@ -76,9 +52,9 @@ class MemcacheCache extends CacheProvider { $flags = null; $this->memcache->get($id, $flags); - + //if memcache has changed the value of "flags", it means the value exists - return ($flags !== null); + return $flags !== null; } /** @@ -89,6 +65,7 @@ class MemcacheCache extends CacheProvider if ($lifeTime > 30 * 24 * 3600) { $lifeTime = time() + $lifeTime; } + return $this->memcache->set($id, $data, 0, (int) $lifeTime); } @@ -115,12 +92,13 @@ class MemcacheCache extends CacheProvider protected function doGetStats() { $stats = $this->memcache->getStats(); - return array( + + return [ Cache::STATS_HITS => $stats['get_hits'], Cache::STATS_MISSES => $stats['get_misses'], Cache::STATS_UPTIME => $stats['uptime'], Cache::STATS_MEMORY_USAGE => $stats['bytes'], Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'], - ); + ]; } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php index 5a0fc0eaf..da966ae26 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php @@ -1,49 +1,29 @@ . - */ namespace Doctrine\Common\Cache; -use \Memcached; +use Memcached; +use function array_keys; +use function preg_match; +use function strlen; +use function strpos; +use function time; /** * Memcached cache provider. * * @link www.doctrine-project.org - * @since 2.2 - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author David Abdemoulaie */ class MemcachedCache extends CacheProvider { - /** - * @var Memcached|null - */ + public const CACHE_ID_MAX_LENGTH = 250; + + /** @var Memcached|null */ private $memcached; /** * Sets the memcache instance to use. * - * @param Memcached $memcached - * * @return void */ public function setMemcached(Memcached $memcached) @@ -82,6 +62,10 @@ class MemcachedCache extends CacheProvider */ protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) { + foreach (array_keys($keysAndValues) as $id) { + $this->validateCacheId($id); + } + if ($lifetime > 30 * 24 * 3600) { $lifetime = time() + $lifetime; } @@ -104,12 +88,24 @@ class MemcachedCache extends CacheProvider */ protected function doSave($id, $data, $lifeTime = 0) { + $this->validateCacheId($id); + if ($lifeTime > 30 * 24 * 3600) { $lifeTime = time() + $lifeTime; } + return $this->memcached->set($id, $data, (int) $lifeTime); } + /** + * {@inheritdoc} + */ + protected function doDeleteMultiple(array $keys) + { + return $this->memcached->deleteMulti($keys) + || $this->memcached->getResultCode() === Memcached::RES_NOTFOUND; + } + /** * {@inheritdoc} */ @@ -136,12 +132,39 @@ class MemcachedCache extends CacheProvider $servers = $this->memcached->getServerList(); $key = $servers[0]['host'] . ':' . $servers[0]['port']; $stats = $stats[$key]; - return array( + + return [ Cache::STATS_HITS => $stats['get_hits'], Cache::STATS_MISSES => $stats['get_misses'], Cache::STATS_UPTIME => $stats['uptime'], Cache::STATS_MEMORY_USAGE => $stats['bytes'], Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'], - ); + ]; + } + + /** + * Validate the cache id + * + * @see https://github.com/memcached/memcached/blob/1.5.12/doc/protocol.txt#L41-L49 + * + * @param string $id + * + * @return void + * + * @throws InvalidCacheId + */ + private function validateCacheId($id) + { + if (strlen($id) > self::CACHE_ID_MAX_LENGTH) { + throw InvalidCacheId::exceedsMaxLength($id, self::CACHE_ID_MAX_LENGTH); + } + + if (strpos($id, ' ') !== false) { + throw InvalidCacheId::containsUnauthorizedCharacter($id, ' '); + } + + if (preg_match('/[\t\r\n]/', $id) === 1) { + throw InvalidCacheId::containsControlCharacter($id); + } } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php index 75fe0ca11..861e4dda3 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php @@ -1,41 +1,22 @@ . - */ namespace Doctrine\Common\Cache; -use MongoBinData; +use InvalidArgumentException; use MongoCollection; -use MongoCursorException; -use MongoDate; +use MongoDB\Collection; +use const E_USER_DEPRECATED; +use function trigger_error; /** * MongoDB cache provider. - * - * @since 1.1 - * @author Jeremy Mikola */ class MongoDBCache extends CacheProvider { /** * The data field will store the serialized PHP value. */ - const DATA_FIELD = 'd'; + public const DATA_FIELD = 'd'; /** * The expiration field will store a MongoDate value indicating when the @@ -52,29 +33,33 @@ class MongoDBCache extends CacheProvider * * @see http://docs.mongodb.org/manual/tutorial/expire-data/ */ - const EXPIRATION_FIELD = 'e'; + public const EXPIRATION_FIELD = 'e'; + + /** @var CacheProvider */ + private $provider; /** - * @var MongoCollection - */ - private $collection; - - /** - * Constructor. - * * This provider will default to the write concern and read preference - * options set on the MongoCollection instance (or inherited from MongoDB or + * options set on the collection instance (or inherited from MongoDB or * MongoClient). Using an unacknowledged write concern (< 1) may make the * return values of delete() and save() unreliable. Reading from secondaries * may make contain() and fetch() unreliable. * * @see http://www.php.net/manual/en/mongo.readpreferences.php * @see http://www.php.net/manual/en/mongo.writeconcerns.php - * @param MongoCollection $collection + * + * @param MongoCollection|Collection $collection */ - public function __construct(MongoCollection $collection) + public function __construct($collection) { - $this->collection = $collection; + if ($collection instanceof MongoCollection) { + @trigger_error('Using a MongoCollection instance for creating a cache adapter is deprecated and will be removed in 2.0', E_USER_DEPRECATED); + $this->provider = new LegacyMongoDBCache($collection); + } elseif ($collection instanceof Collection) { + $this->provider = new ExtMongoDBCache($collection); + } else { + throw new InvalidArgumentException('Invalid collection given - expected a MongoCollection or MongoDB\Collection instance'); + } } /** @@ -82,18 +67,7 @@ class MongoDBCache extends CacheProvider */ protected function doFetch($id) { - $document = $this->collection->findOne(array('_id' => $id), array(self::DATA_FIELD, self::EXPIRATION_FIELD)); - - if ($document === null) { - return false; - } - - if ($this->isExpired($document)) { - $this->doDelete($id); - return false; - } - - return unserialize($document[self::DATA_FIELD]->bin); + return $this->provider->doFetch($id); } /** @@ -101,18 +75,7 @@ class MongoDBCache extends CacheProvider */ protected function doContains($id) { - $document = $this->collection->findOne(array('_id' => $id), array(self::EXPIRATION_FIELD)); - - if ($document === null) { - return false; - } - - if ($this->isExpired($document)) { - $this->doDelete($id); - return false; - } - - return true; + return $this->provider->doContains($id); } /** @@ -120,20 +83,7 @@ class MongoDBCache extends CacheProvider */ protected function doSave($id, $data, $lifeTime = 0) { - try { - $result = $this->collection->update( - array('_id' => $id), - array('$set' => array( - self::EXPIRATION_FIELD => ($lifeTime > 0 ? new MongoDate(time() + $lifeTime) : null), - self::DATA_FIELD => new MongoBinData(serialize($data), MongoBinData::BYTE_ARRAY), - )), - array('upsert' => true, 'multiple' => false) - ); - } catch (MongoCursorException $e) { - return false; - } - - return isset($result['ok']) ? $result['ok'] == 1 : true; + return $this->provider->doSave($id, $data, $lifeTime); } /** @@ -141,9 +91,7 @@ class MongoDBCache extends CacheProvider */ protected function doDelete($id) { - $result = $this->collection->remove(array('_id' => $id)); - - return isset($result['ok']) ? $result['ok'] == 1 : true; + return $this->provider->doDelete($id); } /** @@ -151,10 +99,7 @@ class MongoDBCache extends CacheProvider */ protected function doFlush() { - // Use remove() in lieu of drop() to maintain any collection indexes - $result = $this->collection->remove(); - - return isset($result['ok']) ? $result['ok'] == 1 : true; + return $this->provider->doFlush(); } /** @@ -162,36 +107,6 @@ class MongoDBCache extends CacheProvider */ protected function doGetStats() { - $serverStatus = $this->collection->db->command(array( - 'serverStatus' => 1, - 'locks' => 0, - 'metrics' => 0, - 'recordStats' => 0, - 'repl' => 0, - )); - - $collStats = $this->collection->db->command(array('collStats' => 1)); - - return array( - Cache::STATS_HITS => null, - Cache::STATS_MISSES => null, - Cache::STATS_UPTIME => (isset($serverStatus['uptime']) ? (int) $serverStatus['uptime'] : null), - Cache::STATS_MEMORY_USAGE => (isset($collStats['size']) ? (int) $collStats['size'] : null), - Cache::STATS_MEMORY_AVAILABLE => null, - ); - } - - /** - * Check if the document is expired. - * - * @param array $document - * - * @return bool - */ - private function isExpired(array $document) - { - return isset($document[self::EXPIRATION_FIELD]) && - $document[self::EXPIRATION_FIELD] instanceof MongoDate && - $document[self::EXPIRATION_FIELD]->sec < time(); + return $this->provider->doGetStats(); } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php index df7146d78..e75d6b1c9 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php @@ -1,30 +1,13 @@ . - */ namespace Doctrine\Common\Cache; /** * Interface for cache drivers that allows to get many items at once. * + * @deprecated + * * @link www.doctrine-project.org - * @since 1.4 - * @author Asmir Mustafic */ interface MultiGetCache { @@ -32,8 +15,9 @@ interface MultiGetCache * Returns an associative array of values for keys is found in cache. * * @param string[] $keys Array of keys to retrieve from cache + * * @return mixed[] Array of retrieved values, indexed by the specified keys. * Values that couldn't be retrieved are not contained in this array. */ - function fetchMultiple(array $keys); + public function fetchMultiple(array $keys); } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php index bf87ea9f1..6f059c167 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php @@ -1,41 +1,24 @@ . - */ namespace Doctrine\Common\Cache; /** * Interface for cache drivers that allows to put many items at once. * + * @deprecated + * * @link www.doctrine-project.org - * @since 1.6 - * @author Daniel Gorgan */ interface MultiPutCache { /** * Returns a boolean value indicating if the operation succeeded. * - * @param array $keysAndValues Array of keys and values to save in cache - * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these - * cache entries (0 => infinite lifeTime). + * @param array $keysAndValues Array of keys and values to save in cache + * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these + * cache entries (0 => infinite lifeTime). * * @return bool TRUE if the operation was successful, FALSE if it wasn't. */ - function saveMultiple(array $keysAndValues, $lifetime = 0); + public function saveMultiple(array $keysAndValues, $lifetime = 0); } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php index 5e7519674..c0619991c 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php @@ -1,33 +1,29 @@ . - */ namespace Doctrine\Common\Cache; +use function is_object; +use function method_exists; +use function restore_error_handler; +use function serialize; +use function set_error_handler; +use function sprintf; +use function time; +use function var_export; + /** * Php file cache driver. - * - * @since 2.3 - * @author Fabio B. Silva */ class PhpFileCache extends FileCache { - const EXTENSION = '.doctrinecache.php'; + public const EXTENSION = '.doctrinecache.php'; + + /** + * @var callable + * + * This is cached in a local static variable to avoid instantiating a closure each time we need an empty handler + */ + private static $emptyErrorHandler; /** * {@inheritdoc} @@ -35,6 +31,9 @@ class PhpFileCache extends FileCache public function __construct($directory, $extension = self::EXTENSION, $umask = 0002) { parent::__construct($directory, $extension, $umask); + + self::$emptyErrorHandler = static function () { + }; } /** @@ -44,7 +43,7 @@ class PhpFileCache extends FileCache { $value = $this->includeFileForId($id); - if (! $value) { + if ($value === null) { return false; } @@ -62,7 +61,7 @@ class PhpFileCache extends FileCache { $value = $this->includeFileForId($id); - if (! $value) { + if ($value === null) { return false; } @@ -78,41 +77,40 @@ class PhpFileCache extends FileCache $lifeTime = time() + $lifeTime; } - if (is_object($data) && ! method_exists($data, '__set_state')) { - throw new \InvalidArgumentException( - "Invalid argument given, PhpFileCache only allows objects that implement __set_state() " . - "and fully support var_export(). You can use the FilesystemCache to save arbitrary object " . - "graphs using serialize()/deserialize()." - ); - } + $filename = $this->getFilename($id); - $filename = $this->getFilename($id); - - $value = array( + $value = [ 'lifetime' => $lifeTime, - 'data' => $data - ); + 'data' => $data, + ]; - $value = var_export($value, true); - $code = sprintf('writeFile($filename, $code); } /** - * @param string $id - * - * @return array|false + * @return array|null */ - private function includeFileForId($id) + private function includeFileForId(string $id) : ?array { $fileName = $this->getFilename($id); // note: error suppression is still faster than `file_exists`, `is_file` and `is_readable` - $value = @include $fileName; + set_error_handler(self::$emptyErrorHandler); + + $value = include $fileName; + + restore_error_handler(); if (! isset($value['lifetime'])) { - return false; + return null; } return $value; diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php index bcd27497e..6430d52d7 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php @@ -3,24 +3,21 @@ namespace Doctrine\Common\Cache; use Predis\ClientInterface; +use function array_combine; +use function array_filter; +use function array_map; +use function call_user_func_array; +use function serialize; +use function unserialize; /** * Predis cache provider. - * - * @author othillo */ class PredisCache extends CacheProvider { - /** - * @var ClientInterface - */ + /** @var ClientInterface */ private $client; - /** - * @param ClientInterface $client - * - * @return void - */ public function __construct(ClientInterface $client) { $this->client = $client; @@ -32,7 +29,7 @@ class PredisCache extends CacheProvider protected function doFetch($id) { $result = $this->client->get($id); - if (null === $result) { + if ($result === null) { return false; } @@ -44,7 +41,7 @@ class PredisCache extends CacheProvider */ protected function doFetchMultiple(array $keys) { - $fetchedItems = call_user_func_array(array($this->client, 'mget'), $keys); + $fetchedItems = call_user_func_array([$this->client, 'mget'], $keys); return array_map('unserialize', array_filter(array_combine($keys, $fetchedItems))); } @@ -59,18 +56,20 @@ class PredisCache extends CacheProvider // Keys have lifetime, use SETEX for each of them foreach ($keysAndValues as $key => $value) { - $response = $this->client->setex($key, $lifetime, serialize($value)); + $response = (string) $this->client->setex($key, $lifetime, serialize($value)); - if ((string) $response != 'OK') { - $success = false; + if ($response == 'OK') { + continue; } + + $success = false; } return $success; } // No lifetime, use MSET - $response = $this->client->mset(array_map(function ($value) { + $response = $this->client->mset(array_map(static function ($value) { return serialize($value); }, $keysAndValues)); @@ -108,6 +107,14 @@ class PredisCache extends CacheProvider return $this->client->del($id) >= 0; } + /** + * {@inheritdoc} + */ + protected function doDeleteMultiple(array $keys) + { + return $this->client->del($keys) >= 0; + } + /** * {@inheritdoc} */ @@ -125,12 +132,12 @@ class PredisCache extends CacheProvider { $info = $this->client->info(); - return array( + return [ Cache::STATS_HITS => $info['Stats']['keyspace_hits'], Cache::STATS_MISSES => $info['Stats']['keyspace_misses'], Cache::STATS_UPTIME => $info['Server']['uptime_in_seconds'], Cache::STATS_MEMORY_USAGE => $info['Memory']['used_memory'], - Cache::STATS_MEMORY_AVAILABLE => false - ); + Cache::STATS_MEMORY_AVAILABLE => false, + ]; } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php index 22add6679..324570583 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php @@ -1,45 +1,31 @@ . - */ namespace Doctrine\Common\Cache; use Redis; +use function array_combine; +use function array_diff_key; +use function array_fill_keys; +use function array_filter; +use function array_keys; +use function count; +use function defined; +use function extension_loaded; +use function is_bool; /** * Redis cache provider. * * @link www.doctrine-project.org - * @since 2.2 - * @author Osman Ungur */ class RedisCache extends CacheProvider { - /** - * @var Redis|null - */ + /** @var Redis|null */ private $redis; /** * Sets the redis instance to use. * - * @param Redis $redis - * * @return void */ public function setRedis(Redis $redis) @@ -74,15 +60,21 @@ class RedisCache extends CacheProvider $fetchedItems = array_combine($keys, $this->redis->mget($keys)); // Redis mget returns false for keys that do not exist. So we need to filter those out unless it's the real data. - $foundItems = array(); + $keysToFilter = array_keys(array_filter($fetchedItems, static function ($item) : bool { + return $item === false; + })); - foreach ($fetchedItems as $key => $value) { - if (false !== $value || $this->redis->exists($key)) { - $foundItems[$key] = $value; + if ($keysToFilter) { + $multi = $this->redis->multi(Redis::PIPELINE); + foreach ($keysToFilter as $key) { + $multi->exists($key); } + $existItems = array_filter($multi->exec()); + $missedItemKeys = array_diff_key($keysToFilter, $existItems); + $fetchedItems = array_diff_key($fetchedItems, array_fill_keys($missedItemKeys, true)); } - return $foundItems; + return $fetchedItems; } /** @@ -91,16 +83,14 @@ class RedisCache extends CacheProvider protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) { if ($lifetime) { - $success = true; - // Keys have lifetime, use SETEX for each of them + $multi = $this->redis->multi(Redis::PIPELINE); foreach ($keysAndValues as $key => $value) { - if (!$this->redis->setex($key, $lifetime, $value)) { - $success = false; - } + $multi->setex($key, $lifetime, $value); } + $succeeded = array_filter($multi->exec()); - return $success; + return count($succeeded) == count($keysAndValues); } // No lifetime, use MSET @@ -112,7 +102,13 @@ class RedisCache extends CacheProvider */ protected function doContains($id) { - return $this->redis->exists($id); + $exists = $this->redis->exists($id); + + if (is_bool($exists)) { + return $exists; + } + + return $exists > 0; } /** @@ -132,7 +128,15 @@ class RedisCache extends CacheProvider */ protected function doDelete($id) { - return $this->redis->delete($id) >= 0; + return $this->redis->del($id) >= 0; + } + + /** + * {@inheritdoc} + */ + protected function doDeleteMultiple(array $keys) + { + return $this->redis->del($keys) >= 0; } /** @@ -149,13 +153,14 @@ class RedisCache extends CacheProvider protected function doGetStats() { $info = $this->redis->info(); - return array( + + return [ Cache::STATS_HITS => $info['keyspace_hits'], Cache::STATS_MISSES => $info['keyspace_misses'], Cache::STATS_UPTIME => $info['uptime_in_seconds'], Cache::STATS_MEMORY_USAGE => $info['used_memory'], - Cache::STATS_MEMORY_AVAILABLE => false - ); + Cache::STATS_MEMORY_AVAILABLE => false, + ]; } /** @@ -163,14 +168,10 @@ class RedisCache extends CacheProvider * igbinary support, that is used. Otherwise the default PHP serializer is * used. * - * @return integer One of the Redis::SERIALIZER_* constants + * @return int One of the Redis::SERIALIZER_* constants */ protected function getSerializerValue() { - if (defined('HHVM_VERSION')) { - return Redis::SERIALIZER_PHP; - } - if (defined('Redis::SERIALIZER_IGBINARY') && extension_loaded('igbinary')) { return Redis::SERIALIZER_IGBINARY; } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php index 0bf6e4d44..56deb0774 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php @@ -1,68 +1,50 @@ . - */ namespace Doctrine\Common\Cache; use SQLite3; use SQLite3Result; +use const SQLITE3_ASSOC; +use const SQLITE3_BLOB; +use const SQLITE3_TEXT; +use function array_search; +use function implode; +use function serialize; +use function sprintf; +use function time; +use function unserialize; /** * SQLite3 cache provider. - * - * @since 1.4 - * @author Jake Bell */ class SQLite3Cache extends CacheProvider { /** * The ID field will store the cache key. */ - const ID_FIELD = 'k'; + public const ID_FIELD = 'k'; /** * The data field will store the serialized PHP value. */ - const DATA_FIELD = 'd'; + public const DATA_FIELD = 'd'; /** * The expiration field will store a date value indicating when the * cache entry should expire. */ - const EXPIRATION_FIELD = 'e'; + public const EXPIRATION_FIELD = 'e'; - /** - * @var SQLite3 - */ + /** @var SQLite3 */ private $sqlite; - /** - * @var string - */ + /** @var string */ private $table; /** - * Constructor. - * - * Calling the constructor will ensure that the database file and table + * Calling the constructor will ensure that the database file and table * exist and will create both if they don't. * - * @param SQLite3 $sqlite * @param string $table */ public function __construct(SQLite3 $sqlite, $table) @@ -70,15 +52,20 @@ class SQLite3Cache extends CacheProvider $this->sqlite = $sqlite; $this->table = (string) $table; - list($id, $data, $exp) = $this->getFields(); + $this->ensureTableExists(); + } - return $this->sqlite->exec(sprintf( - 'CREATE TABLE IF NOT EXISTS %s(%s TEXT PRIMARY KEY NOT NULL, %s BLOB, %s INTEGER)', - $table, - $id, - $data, - $exp - )); + private function ensureTableExists() : void + { + $this->sqlite->exec( + sprintf( + 'CREATE TABLE IF NOT EXISTS %s(%s TEXT PRIMARY KEY NOT NULL, %s BLOB, %s INTEGER)', + $this->table, + static::ID_FIELD, + static::DATA_FIELD, + static::EXPIRATION_FIELD + ) + ); } /** @@ -86,11 +73,13 @@ class SQLite3Cache extends CacheProvider */ protected function doFetch($id) { - if ($item = $this->findById($id)) { - return unserialize($item[self::DATA_FIELD]); + $item = $this->findById($id); + + if (! $item) { + return false; } - return false; + return unserialize($item[self::DATA_FIELD]); } /** @@ -98,7 +87,7 @@ class SQLite3Cache extends CacheProvider */ protected function doContains($id) { - return null !== $this->findById($id, false); + return $this->findById($id, false) !== null; } /** @@ -124,7 +113,7 @@ class SQLite3Cache extends CacheProvider */ protected function doDelete($id) { - list($idField) = $this->getFields(); + [$idField] = $this->getFields(); $statement = $this->sqlite->prepare(sprintf( 'DELETE FROM %s WHERE %s = :id', @@ -157,15 +146,14 @@ class SQLite3Cache extends CacheProvider * Find a single row by ID. * * @param mixed $id - * @param bool $includeData * * @return array|null */ - private function findById($id, $includeData = true) + private function findById($id, bool $includeData = true) : ?array { - list($idField) = $fields = $this->getFields(); + [$idField] = $fields = $this->getFields(); - if (!$includeData) { + if (! $includeData) { $key = array_search(static::DATA_FIELD, $fields); unset($fields[$key]); } @@ -199,19 +187,17 @@ class SQLite3Cache extends CacheProvider * * @return array */ - private function getFields() + private function getFields() : array { - return array(static::ID_FIELD, static::DATA_FIELD, static::EXPIRATION_FIELD); + return [static::ID_FIELD, static::DATA_FIELD, static::EXPIRATION_FIELD]; } /** * Check if the item is expired. * * @param array $item - * - * @return bool */ - private function isExpired(array $item) + private function isExpired(array $item) : bool { return isset($item[static::EXPIRATION_FIELD]) && $item[self::EXPIRATION_FIELD] !== null && diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php index a6399ecc1..834b5b7d4 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php @@ -1,25 +1,8 @@ . - */ namespace Doctrine\Common\Cache; class Version { - const VERSION = '1.6.1-DEV'; + public const VERSION = '1.9.0-DEV'; } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php index 65e8456fa..b58f613ad 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php @@ -1,21 +1,4 @@ . - */ namespace Doctrine\Common\Cache; @@ -23,8 +6,6 @@ namespace Doctrine\Common\Cache; * Void cache driver. The cache could be of use in tests where you don`t need to cache anything. * * @link www.doctrine-project.org - * @since 1.5 - * @author Kotlyar Maksim */ class VoidCache extends CacheProvider { diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php index 8a250b29a..972f92f9f 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php @@ -1,34 +1,21 @@ . - */ namespace Doctrine\Common\Cache; +use function count; +use function is_array; +use function wincache_ucache_clear; +use function wincache_ucache_delete; +use function wincache_ucache_exists; +use function wincache_ucache_get; +use function wincache_ucache_info; +use function wincache_ucache_meminfo; +use function wincache_ucache_set; + /** * WinCache cache provider. * * @link www.doctrine-project.org - * @since 2.2 - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author David Abdemoulaie */ class WinCacheCache extends CacheProvider { @@ -90,6 +77,16 @@ class WinCacheCache extends CacheProvider return empty($result); } + /** + * {@inheritdoc} + */ + protected function doDeleteMultiple(array $keys) + { + $result = wincache_ucache_delete($keys); + + return is_array($result) && count($result) !== count($keys); + } + /** * {@inheritdoc} */ @@ -98,12 +95,12 @@ class WinCacheCache extends CacheProvider $info = wincache_ucache_info(); $meminfo = wincache_ucache_meminfo(); - return array( + return [ Cache::STATS_HITS => $info['total_hit_count'], Cache::STATS_MISSES => $info['total_miss_count'], Cache::STATS_UPTIME => $info['total_cache_uptime'], Cache::STATS_MEMORY_USAGE => $meminfo['memory_total'], Cache::STATS_MEMORY_AVAILABLE => $meminfo['memory_free'], - ); + ]; } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php index a2c4ca566..9b3a485ed 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php @@ -1,34 +1,25 @@ . - */ namespace Doctrine\Common\Cache; +use BadMethodCallException; +use const XC_TYPE_VAR; +use function ini_get; +use function serialize; +use function unserialize; +use function xcache_clear_cache; +use function xcache_get; +use function xcache_info; +use function xcache_isset; +use function xcache_set; +use function xcache_unset; + /** * Xcache cache driver. * + * @deprecated + * * @link www.doctrine-project.org - * @since 2.0 - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author David Abdemoulaie */ class XcacheCache extends CacheProvider { @@ -81,12 +72,12 @@ class XcacheCache extends CacheProvider * * @return void * - * @throws \BadMethodCallException When xcache.admin.enable_auth is On. + * @throws BadMethodCallException When xcache.admin.enable_auth is On. */ protected function checkAuthorization() { if (ini_get('xcache.admin.enable_auth')) { - throw new \BadMethodCallException( + throw new BadMethodCallException( 'To use all features of \Doctrine\Common\Cache\XcacheCache, ' . 'you must set "xcache.admin.enable_auth" to "Off" in your php.ini.' ); @@ -101,12 +92,13 @@ class XcacheCache extends CacheProvider $this->checkAuthorization(); $info = xcache_info(XC_TYPE_VAR, 0); - return array( + + return [ Cache::STATS_HITS => $info['hits'], Cache::STATS_MISSES => $info['misses'], Cache::STATS_UPTIME => null, Cache::STATS_MEMORY_USAGE => $info['size'], Cache::STATS_MEMORY_AVAILABLE => $info['avail'], - ); + ]; } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php index 6e35ac823..a6b67ef8b 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php @@ -1,31 +1,16 @@ . - */ namespace Doctrine\Common\Cache; +use function zend_shm_cache_clear; +use function zend_shm_cache_delete; +use function zend_shm_cache_fetch; +use function zend_shm_cache_store; + /** * Zend Data Cache cache driver. * * @link www.doctrine-project.org - * @since 2.0 - * @author Ralph Schindler - * @author Guilherme Blanco */ class ZendDataCache extends CacheProvider { @@ -42,7 +27,7 @@ class ZendDataCache extends CacheProvider */ protected function doContains($id) { - return (false !== zend_shm_cache_fetch($id)); + return zend_shm_cache_fetch($id) !== false; } /** @@ -70,6 +55,7 @@ class ZendDataCache extends CacheProvider if (empty($namespace)) { return zend_shm_cache_clear(); } + return zend_shm_cache_clear($namespace); } diff --git a/vendor/doctrine/collections/CONTRIBUTING.md b/vendor/doctrine/collections/CONTRIBUTING.md index 407a66521..83437dab5 100644 --- a/vendor/doctrine/collections/CONTRIBUTING.md +++ b/vendor/doctrine/collections/CONTRIBUTING.md @@ -18,20 +18,7 @@ branches. ## Coding Standard -We use [doctrine coding standard](https://github.com/doctrine/coding-standard) which is PSR-1 and PSR-2: - -* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md -* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md - -with some exceptions/differences: - -* Keep the nesting of control structures per method as small as possible -* Align equals (=) signs -* Add spaces between assignment, control and return statements -* Prefer early exit over nesting conditions -* Add spaces around a negation if condition ``if ( ! $cond)`` -* Add legal information at the beginning of each source file -* Add ``@author`` [phpDoc](https://www.phpdoc.org/docs/latest/references/phpdoc/tags/author.html) comment at DockBlock of class/interface/trait that you create. +We use the [Doctrine Coding Standard](https://github.com/doctrine/coding-standard). ## Unit-Tests diff --git a/vendor/doctrine/collections/README.md b/vendor/doctrine/collections/README.md index 81e06d0ce..d089e5132 100644 --- a/vendor/doctrine/collections/README.md +++ b/vendor/doctrine/collections/README.md @@ -1,13 +1,78 @@ # Doctrine Collections [![Build Status](https://travis-ci.org/doctrine/collections.svg?branch=master)](https://travis-ci.org/doctrine/collections) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/collections/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/collections/?branch=master) -[![Code Coverage](https://scrutinizer-ci.com/g/doctrine/collections/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/collections/?branch=master) +[![Code Coverage](https://codecov.io/gh/doctrine/collections/branch/master/graph/badge.svg)](https://codecov.io/gh/doctrine/collections/branch/master) Collections Abstraction library ## Changelog +### v1.6.1 + +This release, combined with the release of [`doctrine/collections` `v1.6.1`](https://github.com/doctrine/collections/releases/tag/v1.6.1), +fixes an issue where parsing annotations was not possible +for classes within `doctrine/collections`. + +Specifically, `v1.6.0` introduced Psalm-specific annotations +such as (for example) `@template` and `@template-implements`, +which were both incorrectly recognized as `@template`. + +`@template` has therefore been removed, and instead we use +the prefixed `@psalm-template`, which is no longer parsed +by `doctrine/collections` `v1.6.1` + +Total issues resolved: **1** + +- [186: Use `@psalm-template` annotation to avoid clashes](https://github.com/doctrine/collections/pull/186) thanks to @muglug + +### v1.6.0 + +This release bumps the minimum required PHP version to 7.1.3. + +Following improvements were introduced: + + * `ArrayCollection#filter()` now allows filtering by key, value or both. + * When using the `ClosureExpressionVisitor` over objects with a defined + accessor and property, the accessor is prioritised. + * Updated testing tools and coding standards, autoloading, which also + led to marginal performance improvements + * Introduced generic type docblock declarations from [psalm](https://github.com/vimeo/psalm), + which should allow users to declare `/** @var Collection */` + in their code, and leverage the type propagation deriving from that. + +Total issues resolved: **16** + +- [127: Use PSR-4](https://github.com/doctrine/collections/pull/127) thanks to @Nyholm +- [129: Remove space in method declaration](https://github.com/doctrine/collections/pull/129) thanks to @bounoable +- [130: Update build to add PHPCS and PHPStan](https://github.com/doctrine/collections/pull/130) thanks to @lcobucci +- [131: ClosureExpressionVisitor > Don't duplicate the accessor when the field already starts with it](https://github.com/doctrine/collections/pull/131) thanks to @ruudk +- [139: Apply Doctrine CS 2.1](https://github.com/doctrine/collections/pull/139) thanks to @Majkl578 +- [142: CS 4.0, version composer.lock, merge stages](https://github.com/doctrine/collections/pull/142) thanks to @Majkl578 +- [144: Update to PHPUnit 7](https://github.com/doctrine/collections/pull/144) thanks to @carusogabriel +- [146: Update changelog for v1.4.0 and v1.5.0](https://github.com/doctrine/collections/pull/146) thanks to @GromNaN +- [154: Update index.rst](https://github.com/doctrine/collections/pull/154) thanks to @chraiet +- [158: Extract Selectable method into own documentation section](https://github.com/doctrine/collections/pull/158) thanks to @SenseException +- [160: Update homepage](https://github.com/doctrine/collections/pull/160) thanks to @Majkl578 +- [165: Allow `ArrayCollection#filter()` to filter by key, value or both](https://github.com/doctrine/collections/issues/165) thanks to @0x13a +- [167: Allow `ArrayCollection#filter()` to filter by key and also value](https://github.com/doctrine/collections/pull/167) thanks to @0x13a +- [175: CI: Test against PHP 7.4snapshot instead of nightly (8.0)](https://github.com/doctrine/collections/pull/175) thanks to @Majkl578 +- [177: Generify collections using Psalm](https://github.com/doctrine/collections/pull/177) thanks to @nschoellhorn +- [178: Updated doctrine/coding-standard to 6.0](https://github.com/doctrine/collections/pull/178) thanks to @patrickjahns + +### v1.5.0 + +* [Require PHP 7.1+](https://github.com/doctrine/collections/pull/105) +* [Drop HHVM support](https://github.com/doctrine/collections/pull/118) + +### v1.4.0 + +* [Require PHP 5.6+](https://github.com/doctrine/collections/pull/105) +* [Add `ArrayCollection::createFrom()`](https://github.com/doctrine/collections/pull/91) +* [Support non-camel-case naming](https://github.com/doctrine/collections/pull/57) +* [Comparison `START_WITH`, `END_WITH`](https://github.com/doctrine/collections/pull/78) +* [Comparison `MEMBER_OF`](https://github.com/doctrine/collections/pull/66) +* [Add Contributing guide](https://github.com/doctrine/collections/pull/103) + ### v1.3.0 * [Explicit casting of first and max results in criteria API](https://github.com/doctrine/collections/pull/26) diff --git a/vendor/doctrine/collections/composer.json b/vendor/doctrine/collections/composer.json index 385fa93d2..f0b6a4a21 100644 --- a/vendor/doctrine/collections/composer.json +++ b/vendor/doctrine/collections/composer.json @@ -1,9 +1,14 @@ { "name": "doctrine/collections", "type": "library", - "description": "Collections Abstraction library", - "keywords": ["collections", "array", "iterator"], - "homepage": "http://www.doctrine-project.org", + "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", + "keywords": [ + "php", + "collections", + "array", + "iterators" + ], + "homepage": "https://www.doctrine-project.org/projects/collections.html", "license": "MIT", "authors": [ {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, @@ -13,23 +18,20 @@ {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} ], "require": { - "php": "^5.6 || ^7.0" + "php": "^7.1.3 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^5.7", - "doctrine/coding-standard": "~0.1@dev" + "phpunit/phpunit": "^7.0", + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan-shim": "^0.9.2", + "vimeo/psalm": "^3.8.1" }, "autoload": { - "psr-0": { "Doctrine\\Common\\Collections\\": "lib/" } + "psr-4": { "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" } }, "autoload-dev": { "psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" } - }, - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } } } diff --git a/vendor/doctrine/collections/docs/en/derived-collections.rst b/vendor/doctrine/collections/docs/en/derived-collections.rst new file mode 100644 index 000000000..03d9da5d6 --- /dev/null +++ b/vendor/doctrine/collections/docs/en/derived-collections.rst @@ -0,0 +1,26 @@ +Derived Collections +=================== + +You can create custom collection classes by extending the +``Doctrine\Common\Collections\ArrayCollection`` class. If the +``__construct`` semantics are different from the default ``ArrayCollection`` +you can override the ``createFrom`` method: + +.. code-block:: php + final class DerivedArrayCollection extends ArrayCollection + { + /** @var \stdClass */ + private $foo; + + public function __construct(\stdClass $foo, array $elements = []) + { + $this->foo = $foo; + + parent::__construct($elements); + } + + protected function createFrom(array $elements) : self + { + return new static($this->foo, $elements); + } + } diff --git a/vendor/doctrine/collections/docs/en/expression-builder.rst b/vendor/doctrine/collections/docs/en/expression-builder.rst new file mode 100644 index 000000000..ad4055b54 --- /dev/null +++ b/vendor/doctrine/collections/docs/en/expression-builder.rst @@ -0,0 +1,173 @@ +Expression Builder +================== + +The Expression Builder is a convenient fluent interface for +building expressions to be used with the ``Doctrine\Common\Collections\Criteria`` +class: + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $criteria = new Criteria(); + $criteria->where($expressionBuilder->eq('name', 'jwage')); + $criteria->orWhere($expressionBuilder->eq('name', 'romanb')); + + $collection->matching($criteria); + +The ``ExpressionBuilder`` has the following API: + +andX +---- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->andX( + $expressionBuilder->eq('foo', 1), + $expressionBuilder->eq('bar', 1) + ); + + $collection->matching(new Criteria($expression)); + +orX +--- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->orX( + $expressionBuilder->eq('foo', 1), + $expressionBuilder->eq('bar', 1) + ); + + $collection->matching(new Criteria($expression)); + +eq +--- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->eq('foo', 1); + + $collection->matching(new Criteria($expression)); + +gt +--- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->gt('foo', 1); + + $collection->matching(new Criteria($expression)); + +lt +--- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->lt('foo', 1); + + $collection->matching(new Criteria($expression)); + +gte +--- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->gte('foo', 1); + + $collection->matching(new Criteria($expression)); + +lte +--- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->lte('foo', 1); + + $collection->matching(new Criteria($expression)); + +neq +--- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->neq('foo', 1); + + $collection->matching(new Criteria($expression)); + +isNull +------ + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->isNull('foo'); + + $collection->matching(new Criteria($expression)); + +in +--- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->in('foo', ['value1', 'value2']); + + $collection->matching(new Criteria($expression)); + +notIn +----- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->notIn('foo', ['value1', 'value2']); + + $collection->matching(new Criteria($expression)); + +contains +-------- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->contains('foo', 'value1'); + + $collection->matching(new Criteria($expression)); + +memberOf +-------- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->memberOf('foo', ['value1', 'value2']); + + $collection->matching(new Criteria($expression)); + +startsWith +---------- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->startsWith('foo', 'hello'); + + $collection->matching(new Criteria($expression)); + +endsWith +-------- + +.. code-block:: php + $expressionBuilder = Criteria::expr(); + + $expression = $expressionBuilder->endsWith('foo', 'world'); + + $collection->matching(new Criteria($expression)); diff --git a/vendor/doctrine/collections/docs/en/expressions.rst b/vendor/doctrine/collections/docs/en/expressions.rst new file mode 100644 index 000000000..db943b246 --- /dev/null +++ b/vendor/doctrine/collections/docs/en/expressions.rst @@ -0,0 +1,102 @@ +Expressions +=========== + +The ``Doctrine\Common\Collections\Expr\Comparison`` class +can be used to create expressions to be used with the +``Doctrine\Common\Collections\Criteria`` class. It has the +following operator constants: + +- ``Comparison::EQ`` +- ``Comparison::NEQ`` +- ``Comparison::LT`` +- ``Comparison::LTE`` +- ``Comparison::GT`` +- ``Comparison::GTE`` +- ``Comparison::IS`` +- ``Comparison::IN`` +- ``Comparison::NIN`` +- ``Comparison::CONTAINS`` +- ``Comparison::MEMBER_OF`` +- ``Comparison::STARTS_WITH`` +- ``Comparison::ENDS_WITH`` + +The ``Doctrine\Common\Collections\Criteria`` class has the following +API to be used with expressions: + +where +----- + +Sets the where expression to evaluate when this Criteria is searched for. + +.. code-block:: php + $expr = new Comparison('key', Comparison::EQ, 'value'); + + $criteria->where($expr); + +andWhere +-------- + +Appends the where expression to evaluate when this Criteria is searched for +using an AND with previous expression. + +.. code-block:: php + $expr = new Comparison('key', Comparison::EQ, 'value'); + + $criteria->andWhere($expr); + +orWhere +------- + +Appends the where expression to evaluate when this Criteria is searched for +using an OR with previous expression. + +.. code-block:: php + $expr1 = new Comparison('key', Comparison::EQ, 'value1'); + $expr2 = new Comparison('key', Comparison::EQ, 'value2'); + + $criteria->where($expr1); + $criteria->orWhere($expr2); + +orderBy +------- + +Sets the ordering of the result of this Criteria. + +.. code-block:: php + $criteria->orderBy(['name' => Criteria::ASC]); + +setFirstResult +-------------- + +Set the number of first result that this Criteria should return. + +.. code-block:: php + $criteria->setFirstResult(0); + +getFirstResult +-------------- + +Gets the current first result option of this Criteria. + +.. code-block:: php + $criteria->setFirstResult(10); + + echo $criteria->getFirstResult(); // 10 + +setMaxResults +------------- + +Sets the max results that this Criteria should return. + +.. code-block:: php + $criteria->setMaxResults(20); + +getMaxResults +------------- + +Gets the current max results option of this Criteria. + +.. code-block:: php + $criteria->setMaxResults(20); + + echo $criteria->getMaxResults(); // 20 diff --git a/vendor/doctrine/collections/docs/en/index.rst b/vendor/doctrine/collections/docs/en/index.rst new file mode 100644 index 000000000..447f76e8a --- /dev/null +++ b/vendor/doctrine/collections/docs/en/index.rst @@ -0,0 +1,327 @@ +Introduction +============ + +Doctrine Collections is a library that contains classes for working with +arrays of data. Here is an example using the simple +``Doctrine\Common\Collections\ArrayCollection`` class: + +.. code-block:: php + filter(function($count) { + return $count > 1; + }); // [2, 3] + +Collection Methods +================== + +Doctrine Collections provides an interface named ``Doctrine\Common\Collections\Collection`` +that resembles the nature of a regular PHP array. That is, +it is essentially an **ordered map** that can also be used +like a list. + +A Collection has an internal iterator just like a PHP array. In addition, +a Collection can be iterated with external iterators, which is preferable. +To use an external iterator simply use the foreach language construct to +iterate over the collection, which calls ``getIterator()`` internally, or +explicitly retrieve an iterator though ``getIterator()`` which can then be +used to iterate over the collection. You can not rely on the internal iterator +of the collection being at a certain position unless you explicitly positioned it before. + +The methods available on the interface are: + +add +--- + +Adds an element at the end of the collection. + +.. code-block:: php + $collection->add('test'); + +clear +----- + +Clears the collection, removing all elements. + +.. code-block:: php + $collection->clear(); + +contains +-------- + +Checks whether an element is contained in the collection. This is an O(n) operation, where n is the size of the collection. + +.. code-block:: php + $collection = new Collection(['test']); + + $contains = $collection->contains('test'); // true + +containsKey +----------- + +Checks whether the collection contains an element with the specified key/index. + +.. code-block:: php + $collection = new Collection(['test' => true]); + + $contains = $collection->containsKey('test'); // true + +current +------- + +Gets the element of the collection at the current iterator position. + +.. code-block:: php + $collection = new Collection(['first', 'second', 'third']); + + $current = $collection->current(); // first + +get +--- + +Gets the element at the specified key/index. + +.. code-block:: php + $collection = new Collection([ + 'key' => 'value', + ]); + + $value = $collection->get('key'); // value + +getKeys +------- + +Gets all keys/indices of the collection. + +.. code-block:: php + $collection = new Collection(['a', 'b', 'c']); + + $keys = $collection->getKeys(); // [0, 1, 2] + +getValues +--------- + +Gets all values of the collection. + +.. code-block:: php + $collection = new Collection([ + 'key1' => 'value1', + 'key2' => 'value2', + 'key3' => 'value3', + ]); + + $values = $collection->getValues(); // ['value1', 'value2', 'value3'] + +isEmpty +------- + +Checks whether the collection is empty (contains no elements). + +.. code-block:: php + $collection = new Collection(['a', 'b', 'c']); + + $isEmpty = $collection->isEmpty(); // false + +first +----- + +Sets the internal iterator to the first element in the collection and returns this element. + +.. code-block:: php + $collection = new Collection(['first', 'second', 'third']); + + $first = $collection->first(); // first + +exists +------ + +Tests for the existence of an element that satisfies the given predicate. + +.. code-block:: php + $collection = new Collection(['first', 'second', 'third']); + + $exists = $collection->exists(function($key, $value) { + return $value === 'first'; + }); // true + +filter +------ + +Returns all the elements of this collection that satisfy the predicate. The order of the elements is preserved. + +.. code-block:: php + $collection = new ArrayCollection([1, 2, 3]); + + $filteredCollection = $collection->filter(function($count) { + return $count > 1; + }); // [2, 3] + +forAll +------ + +Tests whether the given predicate holds for all elements of this collection. + +.. code-block:: php + $collection = new ArrayCollection([1, 2, 3]); + + $forAll = $collection->forAll(function($key, $value) { + return $value > 1; + }); // false + +indexOf +------- + +Gets the index/key of a given element. The comparison of two elements is strict, that means not only the value but also the type must match. For objects this means reference equality. + +.. code-block:: php + $collection = new ArrayCollection([1, 2, 3]); + + $indexOf = $collection->indexOf(3); // 2 + +key +--- + +Gets the key/index of the element at the current iterator position. + +.. code-block:: php + $collection = new ArrayCollection([1, 2, 3]); + + $collection->next(); + + $key = $collection->key(); // 1 + +last +---- + +Sets the internal iterator to the last element in the collection and returns this element. + +.. code-block:: php + $collection = new ArrayCollection([1, 2, 3]); + + $last = $collection->last(); // 3 + +map +--- + +Applies the given function to each element in the collection and returns a new collection with the elements returned by the function. + +.. code-block:: php + $collection = new ArrayCollection([1, 2, 3]); + + $mappedCollection = $collection->map(function($value) { + return $value + 1; + }); // [2, 3, 4] + +next +---- + +Moves the internal iterator position to the next element and returns this element. + +.. code-block:: php + $collection = new ArrayCollection([1, 2, 3]); + + $next = $collection->next(); // 2 + +partition +--------- + +Partitions this collection in two collections according to a predicate. Keys are preserved in the resulting collections. + +.. code-block:: php + $collection = new ArrayCollection([1, 2, 3]); + + $mappedCollection = $collection->partition(function($key, $value) { + return $value > 1 + }); // [[2, 3], [1]] + +remove +------ + +Removes the element at the specified index from the collection. + +.. code-block:: php + $collection = new ArrayCollection([1, 2, 3]); + + $collection->remove(0); // [2, 3] + +removeElement +------------- + +Removes the specified element from the collection, if it is found. + +.. code-block:: php + $collection = new ArrayCollection([1, 2, 3]); + + $collection->removeElement(3); // [1, 2] + +set +--- + +Sets an element in the collection at the specified key/index. + +.. code-block:: php + $collection = new ArrayCollection(); + + $collection->set('name', 'jwage'); + +slice +----- + +Extracts a slice of $length elements starting at position $offset from the Collection. If $length is null it returns all elements from $offset to the end of the Collection. Keys have to be preserved by this method. Calling this method will only return the selected slice and NOT change the elements contained in the collection slice is called on. + +.. code-block:: php + $collection = new ArrayCollection([0, 1, 2, 3, 4, 5]); + + $slice = $collection->slice(1, 2); // [1, 2] + +toArray +------- + +Gets a native PHP array representation of the collection. + +.. code-block:: php + $collection = new ArrayCollection([0, 1, 2, 3, 4, 5]); + + $array = $collection->toArray(); // [0, 1, 2, 3, 4, 5] + +Selectable Methods +================== + +Some Doctrine Collections, like ``Doctrine\Common\Collections\ArrayCollection``, +implement an interface named ``Doctrine\Common\Collections\Selectable`` +that offers the usage of a powerful expressions API, where conditions +can be applied to a collection to get a result with matching elements +only. + +matching +-------- + +Selects all elements from a selectable that match the expression and +returns a new collection containing these elements. + +.. code-block:: php + use Doctrine\Common\Collections\Criteria; + use Doctrine\Common\Collections\Expr\Comparison; + + $collection = new ArrayCollection([ + [ + 'name' => 'jwage', + ], + [ + 'name' => 'romanb', + ], + ]); + + $expr = new Comparison('name', '=', 'jwage'); + + $criteria = new Criteria(); + + $criteria->where($expr); + + $matched = $collection->matching($criteria); // ['jwage'] + +You can read more about expressions :ref:`here `. diff --git a/vendor/doctrine/collections/docs/en/lazy-collections.rst b/vendor/doctrine/collections/docs/en/lazy-collections.rst new file mode 100644 index 000000000..b9cafb60b --- /dev/null +++ b/vendor/doctrine/collections/docs/en/lazy-collections.rst @@ -0,0 +1,26 @@ +Lazy Collections +================ + +To create a lazy collection you can extend the +``Doctrine\Common\Collections\AbstractLazyCollection`` class +and define the ``doInitialize`` method. Here is an example where +we lazily query the database for a collection of user records: + +.. code-block:: php + use Doctrine\DBAL\Connection; + + class UsersLazyCollection extends AbstractLazyCollection + { + /** @var Connection */ + private $connection; + + public function __construct(Connection $connection) + { + $this->connection = $connection; + } + + protected function doInitialize() : void + { + $this->collection = $this->connection->fetchAll('SELECT * FROM users'); + } + } diff --git a/vendor/doctrine/collections/docs/en/sidebar.rst b/vendor/doctrine/collections/docs/en/sidebar.rst new file mode 100644 index 000000000..69279a0bb --- /dev/null +++ b/vendor/doctrine/collections/docs/en/sidebar.rst @@ -0,0 +1,8 @@ +.. toctree:: + :depth: 3 + + index + expressions + expression-builder + derived-collections + lazy-collections diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php index b907f8b02..28976f16e 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php @@ -1,21 +1,4 @@ . - */ namespace Doctrine\Common\Collections; @@ -24,21 +7,22 @@ use Closure; /** * Lazy collection that is backed by a concrete collection * - * @author Michaël Gallego - * @since 1.2 + * @phpstan-template TKey + * @psalm-template TKey of array-key + * @psalm-template T + * @template-implements Collection */ abstract class AbstractLazyCollection implements Collection { /** * The backed collection to use * + * @psalm-var Collection * @var Collection */ protected $collection; - /** - * @var boolean - */ + /** @var bool */ protected $initialized = false; /** @@ -47,6 +31,7 @@ abstract class AbstractLazyCollection implements Collection public function count() { $this->initialize(); + return $this->collection->count(); } @@ -56,6 +41,7 @@ abstract class AbstractLazyCollection implements Collection public function add($element) { $this->initialize(); + return $this->collection->add($element); } @@ -74,6 +60,7 @@ abstract class AbstractLazyCollection implements Collection public function contains($element) { $this->initialize(); + return $this->collection->contains($element); } @@ -83,6 +70,7 @@ abstract class AbstractLazyCollection implements Collection public function isEmpty() { $this->initialize(); + return $this->collection->isEmpty(); } @@ -92,6 +80,7 @@ abstract class AbstractLazyCollection implements Collection public function remove($key) { $this->initialize(); + return $this->collection->remove($key); } @@ -101,6 +90,7 @@ abstract class AbstractLazyCollection implements Collection public function removeElement($element) { $this->initialize(); + return $this->collection->removeElement($element); } @@ -110,6 +100,7 @@ abstract class AbstractLazyCollection implements Collection public function containsKey($key) { $this->initialize(); + return $this->collection->containsKey($key); } @@ -119,6 +110,7 @@ abstract class AbstractLazyCollection implements Collection public function get($key) { $this->initialize(); + return $this->collection->get($key); } @@ -128,6 +120,7 @@ abstract class AbstractLazyCollection implements Collection public function getKeys() { $this->initialize(); + return $this->collection->getKeys(); } @@ -137,6 +130,7 @@ abstract class AbstractLazyCollection implements Collection public function getValues() { $this->initialize(); + return $this->collection->getValues(); } @@ -155,6 +149,7 @@ abstract class AbstractLazyCollection implements Collection public function toArray() { $this->initialize(); + return $this->collection->toArray(); } @@ -164,6 +159,7 @@ abstract class AbstractLazyCollection implements Collection public function first() { $this->initialize(); + return $this->collection->first(); } @@ -173,6 +169,7 @@ abstract class AbstractLazyCollection implements Collection public function last() { $this->initialize(); + return $this->collection->last(); } @@ -182,6 +179,7 @@ abstract class AbstractLazyCollection implements Collection public function key() { $this->initialize(); + return $this->collection->key(); } @@ -191,6 +189,7 @@ abstract class AbstractLazyCollection implements Collection public function current() { $this->initialize(); + return $this->collection->current(); } @@ -200,6 +199,7 @@ abstract class AbstractLazyCollection implements Collection public function next() { $this->initialize(); + return $this->collection->next(); } @@ -209,6 +209,7 @@ abstract class AbstractLazyCollection implements Collection public function exists(Closure $p) { $this->initialize(); + return $this->collection->exists($p); } @@ -218,6 +219,7 @@ abstract class AbstractLazyCollection implements Collection public function filter(Closure $p) { $this->initialize(); + return $this->collection->filter($p); } @@ -227,6 +229,7 @@ abstract class AbstractLazyCollection implements Collection public function forAll(Closure $p) { $this->initialize(); + return $this->collection->forAll($p); } @@ -236,6 +239,7 @@ abstract class AbstractLazyCollection implements Collection public function map(Closure $func) { $this->initialize(); + return $this->collection->map($func); } @@ -245,6 +249,7 @@ abstract class AbstractLazyCollection implements Collection public function partition(Closure $p) { $this->initialize(); + return $this->collection->partition($p); } @@ -254,6 +259,7 @@ abstract class AbstractLazyCollection implements Collection public function indexOf($element) { $this->initialize(); + return $this->collection->indexOf($element); } @@ -263,6 +269,7 @@ abstract class AbstractLazyCollection implements Collection public function slice($offset, $length = null) { $this->initialize(); + return $this->collection->slice($offset, $length); } @@ -272,29 +279,44 @@ abstract class AbstractLazyCollection implements Collection public function getIterator() { $this->initialize(); + return $this->collection->getIterator(); } /** * {@inheritDoc} + * + * @psalm-param TKey $offset */ public function offsetExists($offset) { $this->initialize(); + return $this->collection->offsetExists($offset); } /** * {@inheritDoc} + * + * @param int|string $offset + * + * @return mixed + * + * @psalm-param TKey $offset */ public function offsetGet($offset) { $this->initialize(); + return $this->collection->offsetGet($offset); } /** * {@inheritDoc} + * + * @param mixed $value + * + * @psalm-param TKey $offset */ public function offsetSet($offset, $value) { @@ -304,6 +326,8 @@ abstract class AbstractLazyCollection implements Collection /** * {@inheritDoc} + * + * @psalm-param TKey $offset */ public function offsetUnset($offset) { @@ -328,10 +352,12 @@ abstract class AbstractLazyCollection implements Collection */ protected function initialize() { - if ( ! $this->initialized) { - $this->doInitialize(); - $this->initialized = true; + if ($this->initialized) { + return; } + + $this->doInitialize(); + $this->initialized = true; } /** diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php index 7ddd068e5..e65a8fa80 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php @@ -1,27 +1,28 @@ . - */ namespace Doctrine\Common\Collections; use ArrayIterator; use Closure; use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor; +use const ARRAY_FILTER_USE_BOTH; +use function array_filter; +use function array_key_exists; +use function array_keys; +use function array_map; +use function array_reverse; +use function array_search; +use function array_slice; +use function array_values; +use function count; +use function current; +use function end; +use function in_array; +use function key; +use function next; +use function reset; +use function spl_object_hash; +use function uasort; /** * An ArrayCollection is a Collection implementation that wraps a regular PHP array. @@ -31,16 +32,18 @@ use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor; * serialize a collection use {@link toArray()} and reconstruct the collection * manually. * - * @since 2.0 - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel + * @phpstan-template TKey + * @psalm-template TKey of array-key + * @psalm-template T + * @template-implements Collection + * @template-implements Selectable */ class ArrayCollection implements Collection, Selectable { /** * An array containing the entries of this collection. * + * @psalm-var array * @var array */ private $elements; @@ -49,27 +52,14 @@ class ArrayCollection implements Collection, Selectable * Initializes a new ArrayCollection. * * @param array $elements + * + * @psalm-param array $elements */ - public function __construct(array $elements = array()) + public function __construct(array $elements = []) { $this->elements = $elements; } - /** - * Creates a new instance from the specified elements. - * - * This method is provided for derived classes to specify how a new - * instance should be created when constructor semantics have changed. - * - * @param array $elements Elements. - * - * @return static - */ - protected function createFrom(array $elements) - { - return new static($elements); - } - /** * {@inheritDoc} */ @@ -86,6 +76,24 @@ class ArrayCollection implements Collection, Selectable return reset($this->elements); } + /** + * Creates a new instance from the specified elements. + * + * This method is provided for derived classes to specify how a new + * instance should be created when constructor semantics have changed. + * + * @param array $elements Elements. + * + * @return static + * + * @psalm-param array $elements + * @psalm-return static + */ + protected function createFrom(array $elements) + { + return new static($elements); + } + /** * {@inheritDoc} */ @@ -123,7 +131,7 @@ class ArrayCollection implements Collection, Selectable */ public function remove($key) { - if ( ! isset($this->elements[$key]) && ! array_key_exists($key, $this->elements)) { + if (! isset($this->elements[$key]) && ! array_key_exists($key, $this->elements)) { return null; } @@ -153,6 +161,8 @@ class ArrayCollection implements Collection, Selectable * Required by interface ArrayAccess. * * {@inheritDoc} + * + * @psalm-param TKey $offset */ public function offsetExists($offset) { @@ -163,6 +173,8 @@ class ArrayCollection implements Collection, Selectable * Required by interface ArrayAccess. * * {@inheritDoc} + * + * @psalm-param TKey $offset */ public function offsetGet($offset) { @@ -176,8 +188,10 @@ class ArrayCollection implements Collection, Selectable */ public function offsetSet($offset, $value) { - if ( ! isset($offset)) { - return $this->add($value); + if (! isset($offset)) { + $this->add($value); + + return; } $this->set($offset, $value); @@ -187,10 +201,12 @@ class ArrayCollection implements Collection, Selectable * Required by interface ArrayAccess. * * {@inheritDoc} + * + * @psalm-param TKey $offset */ public function offsetUnset($offset) { - return $this->remove($offset); + $this->remove($offset); } /** @@ -236,7 +252,7 @@ class ArrayCollection implements Collection, Selectable */ public function get($key) { - return isset($this->elements[$key]) ? $this->elements[$key] : null; + return $this->elements[$key] ?? null; } /** @@ -273,6 +289,11 @@ class ArrayCollection implements Collection, Selectable /** * {@inheritDoc} + * + * @psalm-suppress InvalidPropertyAssignmentValue + * + * This breaks assumptions about the template type, but it would + * be a backwards-incompatible change to remove this method */ public function add($element) { @@ -301,6 +322,12 @@ class ArrayCollection implements Collection, Selectable /** * {@inheritDoc} + * + * @return static + * + * @psalm-template U + * @psalm-param Closure(T=):U $func + * @psalm-return static */ public function map(Closure $func) { @@ -309,10 +336,14 @@ class ArrayCollection implements Collection, Selectable /** * {@inheritDoc} + * + * @return static + * + * @psalm-return static */ public function filter(Closure $p) { - return $this->createFrom(array_filter($this->elements, $p)); + return $this->createFrom(array_filter($this->elements, $p, ARRAY_FILTER_USE_BOTH)); } /** @@ -321,7 +352,7 @@ class ArrayCollection implements Collection, Selectable public function forAll(Closure $p) { foreach ($this->elements as $key => $element) { - if ( ! $p($key, $element)) { + if (! $p($key, $element)) { return false; } } @@ -334,7 +365,7 @@ class ArrayCollection implements Collection, Selectable */ public function partition(Closure $p) { - $matches = $noMatches = array(); + $matches = $noMatches = []; foreach ($this->elements as $key => $element) { if ($p($key, $element)) { @@ -344,7 +375,7 @@ class ArrayCollection implements Collection, Selectable } } - return array($this->createFrom($matches), $this->createFrom($noMatches)); + return [$this->createFrom($matches), $this->createFrom($noMatches)]; } /** @@ -354,7 +385,7 @@ class ArrayCollection implements Collection, Selectable */ public function __toString() { - return __CLASS__ . '@' . spl_object_hash($this); + return self::class . '@' . spl_object_hash($this); } /** @@ -362,7 +393,7 @@ class ArrayCollection implements Collection, Selectable */ public function clear() { - $this->elements = array(); + $this->elements = []; } /** @@ -387,10 +418,12 @@ class ArrayCollection implements Collection, Selectable $filtered = array_filter($filtered, $filter); } - if ($orderings = $criteria->getOrderings()) { + $orderings = $criteria->getOrderings(); + + if ($orderings) { $next = null; foreach (array_reverse($orderings) as $field => $ordering) { - $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::DESC ? -1 : 1, $next); + $next = ClosureExpressionVisitor::sortByField($field, $ordering === Criteria::DESC ? -1 : 1, $next); } uasort($filtered, $next); @@ -400,7 +433,7 @@ class ArrayCollection implements Collection, Selectable $length = $criteria->getMaxResults(); if ($offset || $length) { - $filtered = array_slice($filtered, (int)$offset, $length); + $filtered = array_slice($filtered, (int) $offset, $length); } return $this->createFrom($filtered); diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php index 8792f7a5b..ab1e3f890 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php @@ -1,21 +1,4 @@ . - */ namespace Doctrine\Common\Collections; @@ -41,10 +24,11 @@ use IteratorAggregate; * position unless you explicitly positioned it before. Prefer iteration with * external iterators. * - * @since 2.0 - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel + * @phpstan-template TKey + * @psalm-template TKey of array-key + * @psalm-template T + * @template-extends IteratorAggregate + * @template-extends ArrayAccess */ interface Collection extends Countable, IteratorAggregate, ArrayAccess { @@ -53,7 +37,9 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * * @param mixed $element The element to add. * - * @return boolean Always TRUE. + * @return true Always TRUE. + * + * @psalm-param T $element */ public function add($element); @@ -70,23 +56,28 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * * @param mixed $element The element to search for. * - * @return boolean TRUE if the collection contains the element, FALSE otherwise. + * @return bool TRUE if the collection contains the element, FALSE otherwise. + * + * @psalm-param T $element */ public function contains($element); /** * Checks whether the collection is empty (contains no elements). * - * @return boolean TRUE if the collection is empty, FALSE otherwise. + * @return bool TRUE if the collection is empty, FALSE otherwise. */ public function isEmpty(); /** * Removes the element at the specified index from the collection. * - * @param string|integer $key The kex/index of the element to remove. + * @param string|int $key The key/index of the element to remove. * * @return mixed The removed element or NULL, if the collection did not contain the element. + * + * @psalm-param TKey $key + * @psalm-return T|null */ public function remove($key); @@ -95,34 +86,43 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * * @param mixed $element The element to remove. * - * @return boolean TRUE if this collection contained the specified element, FALSE otherwise. + * @return bool TRUE if this collection contained the specified element, FALSE otherwise. + * + * @psalm-param T $element */ public function removeElement($element); /** * Checks whether the collection contains an element with the specified key/index. * - * @param string|integer $key The key/index to check for. + * @param string|int $key The key/index to check for. * - * @return boolean TRUE if the collection contains an element with the specified key/index, - * FALSE otherwise. + * @return bool TRUE if the collection contains an element with the specified key/index, + * FALSE otherwise. + * + * @psalm-param TKey $key */ public function containsKey($key); /** * Gets the element at the specified key/index. * - * @param string|integer $key The key/index of the element to retrieve. + * @param string|int $key The key/index of the element to retrieve. * * @return mixed + * + * @psalm-param TKey $key + * @psalm-return T|null */ public function get($key); /** * Gets all keys/indices of the collection. * - * @return array The keys/indices of the collection, in the order of the corresponding + * @return int[]|string[] The keys/indices of the collection, in the order of the corresponding * elements in the collection. + * + * @psalm-return TKey[] */ public function getKeys(); @@ -131,16 +131,21 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * * @return array The values of all elements in the collection, in the order they * appear in the collection. + * + * @psalm-return T[] */ public function getValues(); /** * Sets an element in the collection at the specified key/index. * - * @param string|integer $key The key/index of the element to set. - * @param mixed $value The element to set. + * @param string|int $key The key/index of the element to set. + * @param mixed $value The element to set. * * @return void + * + * @psalm-param TKey $key + * @psalm-param T $value */ public function set($key, $value); @@ -148,6 +153,8 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * Gets a native PHP array representation of the collection. * * @return array + * + * @psalm-return array */ public function toArray(); @@ -155,6 +162,8 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * Sets the internal iterator to the first element in the collection and returns this element. * * @return mixed + * + * @psalm-return T|false */ public function first(); @@ -162,13 +171,17 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * Sets the internal iterator to the last element in the collection and returns this element. * * @return mixed + * + * @psalm-return T|false */ public function last(); /** * Gets the key/index of the element at the current iterator position. * - * @return int|string + * @return int|string|null + * + * @psalm-return TKey|null */ public function key(); @@ -176,6 +189,8 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * Gets the element of the collection at the current iterator position. * * @return mixed + * + * @psalm-return T|false */ public function current(); @@ -183,6 +198,8 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * Moves the internal iterator position to the next element and returns this element. * * @return mixed + * + * @psalm-return T|false */ public function next(); @@ -191,7 +208,9 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * * @param Closure $p The predicate. * - * @return boolean TRUE if the predicate is TRUE for at least one element, FALSE otherwise. + * @return bool TRUE if the predicate is TRUE for at least one element, FALSE otherwise. + * + * @psalm-param Closure(TKey=, T=):bool $p */ public function exists(Closure $p); @@ -202,6 +221,9 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * @param Closure $p The predicate used for filtering. * * @return Collection A collection with the results of the filter operation. + * + * @psalm-param Closure(T=):bool $p + * @psalm-return Collection */ public function filter(Closure $p); @@ -210,7 +232,9 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * * @param Closure $p The predicate. * - * @return boolean TRUE, if the predicate yields TRUE for all elements, FALSE otherwise. + * @return bool TRUE, if the predicate yields TRUE for all elements, FALSE otherwise. + * + * @psalm-param Closure(TKey=, T=):bool $p */ public function forAll(Closure $p); @@ -218,9 +242,11 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * Applies the given function to each element in the collection and returns * a new collection with the elements returned by the function. * - * @param Closure $func - * * @return Collection + * + * @psalm-template U + * @psalm-param Closure(T=):U $func + * @psalm-return Collection */ public function map(Closure $func); @@ -230,9 +256,12 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * * @param Closure $p The predicate on which to partition. * - * @return array An array with two elements. The first element contains the collection - * of elements where the predicate returned TRUE, the second element - * contains the collection of elements where the predicate returned FALSE. + * @return Collection[] An array with two elements. The first element contains the collection + * of elements where the predicate returned TRUE, the second element + * contains the collection of elements where the predicate returned FALSE. + * + * @psalm-param Closure(TKey=, T=):bool $p + * @psalm-return array{0: Collection, 1: Collection} */ public function partition(Closure $p); @@ -244,6 +273,9 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * @param mixed $element The element to search for. * * @return int|string|bool The key/index of the element or FALSE if the element was not found. + * + * @psalm-param T $element + * @psalm-return TKey|false */ public function indexOf($element); @@ -258,6 +290,8 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess * @param int|null $length The maximum number of elements to return, or null for no limit. * * @return array + * + * @psalm-return array */ public function slice($offset, $length = null); } diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Criteria.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Criteria.php index 3f9d43a82..6ddaf5e40 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Criteria.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Criteria.php @@ -1,68 +1,34 @@ . - */ namespace Doctrine\Common\Collections; -use Doctrine\Common\Collections\Expr\Expression; use Doctrine\Common\Collections\Expr\CompositeExpression; +use Doctrine\Common\Collections\Expr\Expression; +use function array_map; +use function strtoupper; /** * Criteria for filtering Selectable collections. - * - * @author Benjamin Eberlei - * @since 2.3 */ class Criteria { - /** - * @var string - */ - const ASC = 'ASC'; + public const ASC = 'ASC'; - /** - * @var string - */ - const DESC = 'DESC'; + public const DESC = 'DESC'; - /** - * @var \Doctrine\Common\Collections\ExpressionBuilder|null - */ + /** @var ExpressionBuilder|null */ private static $expressionBuilder; - /** - * @var \Doctrine\Common\Collections\Expr\Expression|null - */ + /** @var Expression|null */ private $expression; - /** - * @var string[] - */ - private $orderings = array(); + /** @var string[] */ + private $orderings = []; - /** - * @var int|null - */ + /** @var int|null */ private $firstResult; - /** - * @var int|null - */ + /** @var int|null */ private $maxResults; /** @@ -78,7 +44,7 @@ class Criteria /** * Returns the expression builder. * - * @return \Doctrine\Common\Collections\ExpressionBuilder + * @return ExpressionBuilder */ public static function expr() { @@ -92,28 +58,27 @@ class Criteria /** * Construct a new Criteria. * - * @param Expression $expression * @param string[]|null $orderings * @param int|null $firstResult * @param int|null $maxResults */ - public function __construct(Expression $expression = null, array $orderings = null, $firstResult = null, $maxResults = null) + public function __construct(?Expression $expression = null, ?array $orderings = null, $firstResult = null, $maxResults = null) { $this->expression = $expression; $this->setFirstResult($firstResult); $this->setMaxResults($maxResults); - if (null !== $orderings) { - $this->orderBy($orderings); + if ($orderings === null) { + return; } + + $this->orderBy($orderings); } /** * Sets the where expression to evaluate when this Criteria is searched for. * - * @param Expression $expression - * * @return Criteria */ public function where(Expression $expression) @@ -127,8 +92,6 @@ class Criteria * Appends the where expression to evaluate when this Criteria is searched for * using an AND with previous expression. * - * @param Expression $expression - * * @return Criteria */ public function andWhere(Expression $expression) @@ -137,9 +100,10 @@ class Criteria return $this->where($expression); } - $this->expression = new CompositeExpression(CompositeExpression::TYPE_AND, array( - $this->expression, $expression - )); + $this->expression = new CompositeExpression( + CompositeExpression::TYPE_AND, + [$this->expression, $expression] + ); return $this; } @@ -148,8 +112,6 @@ class Criteria * Appends the where expression to evaluate when this Criteria is searched for * using an OR with previous expression. * - * @param Expression $expression - * * @return Criteria */ public function orWhere(Expression $expression) @@ -158,9 +120,10 @@ class Criteria return $this->where($expression); } - $this->expression = new CompositeExpression(CompositeExpression::TYPE_OR, array( - $this->expression, $expression - )); + $this->expression = new CompositeExpression( + CompositeExpression::TYPE_OR, + [$this->expression, $expression] + ); return $this; } @@ -200,7 +163,7 @@ class Criteria public function orderBy(array $orderings) { $this->orderings = array_map( - function ($ordering) { + static function (string $ordering) : string { return strtoupper($ordering) === Criteria::ASC ? Criteria::ASC : Criteria::DESC; }, $orderings @@ -228,7 +191,7 @@ class Criteria */ public function setFirstResult($firstResult) { - $this->firstResult = null === $firstResult ? null : (int) $firstResult; + $this->firstResult = $firstResult === null ? null : (int) $firstResult; return $this; } @@ -252,7 +215,7 @@ class Criteria */ public function setMaxResults($maxResults) { - $this->maxResults = null === $maxResults ? null : (int) $maxResults; + $this->maxResults = $maxResults === null ? null : (int) $maxResults; return $this; } diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php index 1239aa393..90ec79496 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php @@ -1,32 +1,27 @@ . - */ namespace Doctrine\Common\Collections\Expr; +use ArrayAccess; +use Closure; +use RuntimeException; +use function in_array; +use function is_array; +use function is_scalar; +use function iterator_to_array; +use function method_exists; +use function preg_match; +use function preg_replace_callback; +use function strlen; +use function strpos; +use function strtoupper; +use function substr; + /** * Walks an expression graph and turns it into a PHP closure. * * This closure can be used with {@Collection#filter()} and is used internally * by {@ArrayCollection#select()}. - * - * @author Benjamin Eberlei - * @since 2.3 */ class ClosureExpressionVisitor extends ExpressionVisitor { @@ -35,8 +30,8 @@ class ClosureExpressionVisitor extends ExpressionVisitor * directly or indirectly (through an accessor get*, is*, or a magic * method, __get, __call). * - * @param object $object - * @param string $field + * @param object|array $object + * @param string $field * * @return mixed */ @@ -46,16 +41,18 @@ class ClosureExpressionVisitor extends ExpressionVisitor return $object[$field]; } - $accessors = array('get', 'is'); + $accessors = ['get', 'is']; foreach ($accessors as $accessor) { $accessor .= $field; - if ( ! method_exists($object, $accessor)) { - continue; + if (method_exists($object, $accessor)) { + return $object->$accessor(); } + } - return $object->$accessor(); + if (preg_match('/^is[A-Z]+/', $field) === 1 && method_exists($object, $field)) { + return $object->$field(); } // __call should be triggered for get. @@ -65,7 +62,7 @@ class ClosureExpressionVisitor extends ExpressionVisitor return $object->$accessor(); } - if ($object instanceof \ArrayAccess) { + if ($object instanceof ArrayAccess) { return $object[$field]; } @@ -74,17 +71,16 @@ class ClosureExpressionVisitor extends ExpressionVisitor } // camelcase field name to support different variable naming conventions - $ccField = preg_replace_callback('/_(.?)/', function($matches) { return strtoupper($matches[1]); }, $field); + $ccField = preg_replace_callback('/_(.?)/', static function ($matches) { + return strtoupper($matches[1]); + }, $field); foreach ($accessors as $accessor) { $accessor .= $ccField; - - if ( ! method_exists($object, $accessor)) { - continue; + if (method_exists($object, $accessor)) { + return $object->$accessor(); } - - return $object->$accessor(); } return $object->$field; @@ -93,29 +89,29 @@ class ClosureExpressionVisitor extends ExpressionVisitor /** * Helper for sorting arrays of objects based on multiple fields + orientations. * - * @param string $name - * @param int $orientation - * @param \Closure $next + * @param string $name + * @param int $orientation * - * @return \Closure + * @return Closure */ - public static function sortByField($name, $orientation = 1, \Closure $next = null) + public static function sortByField($name, $orientation = 1, ?Closure $next = null) { - if ( ! $next) { - $next = function() { + if (! $next) { + $next = static function () : int { return 0; }; } - return function ($a, $b) use ($name, $next, $orientation) { + return static function ($a, $b) use ($name, $next, $orientation) : int { $aValue = ClosureExpressionVisitor::getObjectFieldValue($a, $name); + $bValue = ClosureExpressionVisitor::getObjectFieldValue($b, $name); if ($aValue === $bValue) { return $next($a, $b); } - return (($aValue > $bValue) ? 1 : -1) * $orientation; + return ($aValue > $bValue ? 1 : -1) * $orientation; }; } @@ -129,72 +125,77 @@ class ClosureExpressionVisitor extends ExpressionVisitor switch ($comparison->getOperator()) { case Comparison::EQ: - return function ($object) use ($field, $value) { + return static function ($object) use ($field, $value) : bool { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) === $value; }; case Comparison::NEQ: - return function ($object) use ($field, $value) { + return static function ($object) use ($field, $value) : bool { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) !== $value; }; case Comparison::LT: - return function ($object) use ($field, $value) { + return static function ($object) use ($field, $value) : bool { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) < $value; }; case Comparison::LTE: - return function ($object) use ($field, $value) { + return static function ($object) use ($field, $value) : bool { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) <= $value; }; case Comparison::GT: - return function ($object) use ($field, $value) { + return static function ($object) use ($field, $value) : bool { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) > $value; }; case Comparison::GTE: - return function ($object) use ($field, $value) { + return static function ($object) use ($field, $value) : bool { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) >= $value; }; case Comparison::IN: - return function ($object) use ($field, $value) { - return in_array(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); + return static function ($object) use ($field, $value) : bool { + $fieldValue = ClosureExpressionVisitor::getObjectFieldValue($object, $field); + + return in_array($fieldValue, $value, is_scalar($fieldValue)); }; case Comparison::NIN: - return function ($object) use ($field, $value) { - return ! in_array(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); + return static function ($object) use ($field, $value) : bool { + $fieldValue = ClosureExpressionVisitor::getObjectFieldValue($object, $field); + + return ! in_array($fieldValue, $value, is_scalar($fieldValue)); }; case Comparison::CONTAINS: - return function ($object) use ($field, $value) { - return false !== strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); + return static function ($object) use ($field, $value) { + return strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value) !== false; }; case Comparison::MEMBER_OF: - return function ($object) use ($field, $value) { + return static function ($object) use ($field, $value) : bool { $fieldValues = ClosureExpressionVisitor::getObjectFieldValue($object, $field); - if (!is_array($fieldValues)) { + + if (! is_array($fieldValues)) { $fieldValues = iterator_to_array($fieldValues); } - return in_array($value, $fieldValues); + + return in_array($value, $fieldValues, true); }; case Comparison::STARTS_WITH: - return function ($object) use ($field, $value) { - return 0 === strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); + return static function ($object) use ($field, $value) : bool { + return strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value) === 0; }; case Comparison::ENDS_WITH: - return function ($object) use ($field, $value) { + return static function ($object) use ($field, $value) : bool { return $value === substr(ClosureExpressionVisitor::getObjectFieldValue($object, $field), -strlen($value)); }; - default: - throw new \RuntimeException("Unknown comparison operator: " . $comparison->getOperator()); + throw new RuntimeException('Unknown comparison operator: ' . $comparison->getOperator()); } } @@ -211,54 +212,50 @@ class ClosureExpressionVisitor extends ExpressionVisitor */ public function walkCompositeExpression(CompositeExpression $expr) { - $expressionList = array(); + $expressionList = []; foreach ($expr->getExpressionList() as $child) { $expressionList[] = $this->dispatch($child); } - switch($expr->getType()) { + switch ($expr->getType()) { case CompositeExpression::TYPE_AND: return $this->andExpressions($expressionList); - case CompositeExpression::TYPE_OR: return $this->orExpressions($expressionList); - default: - throw new \RuntimeException("Unknown composite " . $expr->getType()); + throw new RuntimeException('Unknown composite ' . $expr->getType()); } } /** * @param array $expressions - * - * @return callable */ - private function andExpressions($expressions) + private function andExpressions(array $expressions) : callable { - return function ($object) use ($expressions) { + return static function ($object) use ($expressions) : bool { foreach ($expressions as $expression) { - if ( ! $expression($object)) { + if (! $expression($object)) { return false; } } + return true; }; } /** * @param array $expressions - * - * @return callable */ - private function orExpressions($expressions) + private function orExpressions(array $expressions) : callable { - return function ($object) use ($expressions) { + return static function ($object) use ($expressions) : bool { foreach ($expressions as $expression) { if ($expression($object)) { return true; } } + return false; }; } diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php index ec9a9f48a..13e193cb5 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php @@ -1,58 +1,33 @@ . - */ namespace Doctrine\Common\Collections\Expr; /** * Comparison of a field with a value by the given operator. - * - * @author Benjamin Eberlei - * @since 2.3 */ class Comparison implements Expression { - const EQ = '='; - const NEQ = '<>'; - const LT = '<'; - const LTE = '<='; - const GT = '>'; - const GTE = '>='; - const IS = '='; // no difference with EQ - const IN = 'IN'; - const NIN = 'NIN'; - const CONTAINS = 'CONTAINS'; - const MEMBER_OF = 'MEMBER_OF'; - const STARTS_WITH = 'STARTS_WITH'; - const ENDS_WITH = 'ENDS_WITH'; - /** - * @var string - */ + public const EQ = '='; + public const NEQ = '<>'; + public const LT = '<'; + public const LTE = '<='; + public const GT = '>'; + public const GTE = '>='; + public const IS = '='; // no difference with EQ + public const IN = 'IN'; + public const NIN = 'NIN'; + public const CONTAINS = 'CONTAINS'; + public const MEMBER_OF = 'MEMBER_OF'; + public const STARTS_WITH = 'STARTS_WITH'; + public const ENDS_WITH = 'ENDS_WITH'; + + /** @var string */ private $field; - /** - * @var string - */ + /** @var string */ private $op; - /** - * @var Value - */ + /** @var Value */ private $value; /** @@ -62,12 +37,12 @@ class Comparison implements Expression */ public function __construct($field, $operator, $value) { - if ( ! ($value instanceof Value)) { + if (! ($value instanceof Value)) { $value = new Value($value); } $this->field = $field; - $this->op = $operator; + $this->op = $operator; $this->value = $value; } diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/CompositeExpression.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/CompositeExpression.php index 3613c0274..e1f7114de 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/CompositeExpression.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/CompositeExpression.php @@ -1,50 +1,28 @@ . - */ namespace Doctrine\Common\Collections\Expr; +use RuntimeException; + /** * Expression of Expressions combined by AND or OR operation. - * - * @author Benjamin Eberlei - * @since 2.3 */ class CompositeExpression implements Expression { - const TYPE_AND = 'AND'; - const TYPE_OR = 'OR'; + public const TYPE_AND = 'AND'; + public const TYPE_OR = 'OR'; - /** - * @var string - */ + /** @var string */ private $type; - /** - * @var Expression[] - */ - private $expressions = array(); + /** @var Expression[] */ + private $expressions = []; /** * @param string $type * @param array $expressions * - * @throws \RuntimeException + * @throws RuntimeException */ public function __construct($type, array $expressions) { @@ -52,10 +30,10 @@ class CompositeExpression implements Expression foreach ($expressions as $expr) { if ($expr instanceof Value) { - throw new \RuntimeException("Values are not supported expressions as children of and/or expressions."); + throw new RuntimeException('Values are not supported expressions as children of and/or expressions.'); } - if ( ! ($expr instanceof Expression)) { - throw new \RuntimeException("No expression given to CompositeExpression."); + if (! ($expr instanceof Expression)) { + throw new RuntimeException('No expression given to CompositeExpression.'); } $this->expressions[] = $expr; diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Expression.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Expression.php index 68db767c0..f40d529b6 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Expression.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Expression.php @@ -1,34 +1,13 @@ . - */ namespace Doctrine\Common\Collections\Expr; /** * Expression for the {@link Selectable} interface. - * - * @author Benjamin Eberlei */ interface Expression { /** - * @param ExpressionVisitor $visitor - * * @return mixed */ public function visit(ExpressionVisitor $visitor); diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ExpressionVisitor.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ExpressionVisitor.php index 080afdc6d..baf1ea8f6 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ExpressionVisitor.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ExpressionVisitor.php @@ -1,37 +1,19 @@ . - */ namespace Doctrine\Common\Collections\Expr; +use RuntimeException; +use function get_class; + /** * An Expression visitor walks a graph of expressions and turns them into a * query for the underlying implementation. - * - * @author Benjamin Eberlei */ abstract class ExpressionVisitor { /** * Converts a comparison expression into the target query language output. * - * @param Comparison $comparison - * * @return mixed */ abstract public function walkComparison(Comparison $comparison); @@ -39,8 +21,6 @@ abstract class ExpressionVisitor /** * Converts a value expression into the target query language part. * - * @param Value $value - * * @return mixed */ abstract public function walkValue(Value $value); @@ -48,8 +28,6 @@ abstract class ExpressionVisitor /** * Converts a composite expression into the target query language output. * - * @param CompositeExpression $expr - * * @return mixed */ abstract public function walkCompositeExpression(CompositeExpression $expr); @@ -57,26 +35,21 @@ abstract class ExpressionVisitor /** * Dispatches walking an expression to the appropriate handler. * - * @param Expression $expr - * * @return mixed * - * @throws \RuntimeException + * @throws RuntimeException */ public function dispatch(Expression $expr) { switch (true) { - case ($expr instanceof Comparison): + case $expr instanceof Comparison: return $this->walkComparison($expr); - - case ($expr instanceof Value): + case $expr instanceof Value: return $this->walkValue($expr); - - case ($expr instanceof CompositeExpression): + case $expr instanceof CompositeExpression: return $this->walkCompositeExpression($expr); - default: - throw new \RuntimeException("Unknown Expression " . get_class($expr)); + throw new RuntimeException('Unknown Expression ' . get_class($expr)); } } } diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php index 7f6e83143..0830286e1 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php @@ -1,29 +1,10 @@ . - */ namespace Doctrine\Common\Collections\Expr; class Value implements Expression { - /** - * @var mixed - */ + /** @var mixed */ private $value; /** diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php index 1a44a7ba8..4c0f5fdc8 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php @@ -1,27 +1,11 @@ . - */ namespace Doctrine\Common\Collections; use Doctrine\Common\Collections\Expr\Comparison; use Doctrine\Common\Collections\Expr\CompositeExpression; use Doctrine\Common\Collections\Expr\Value; +use function func_get_args; /** * Builder for Expressions in the {@link Selectable} interface. @@ -29,14 +13,11 @@ use Doctrine\Common\Collections\Expr\Value; * Important Notice for interoperable code: You have to use scalar * values only for comparisons, otherwise the behavior of the comparison * may be different between implementations (Array vs ORM vs ODM). - * - * @author Benjamin Eberlei - * @since 2.3 */ class ExpressionBuilder { /** - * @param mixed $x + * @param mixed ...$x * * @return CompositeExpression */ @@ -46,7 +27,7 @@ class ExpressionBuilder } /** - * @param mixed $x + * @param mixed ...$x * * @return CompositeExpression */ @@ -133,7 +114,7 @@ class ExpressionBuilder /** * @param string $field - * @param mixed $values + * @param array $values * * @return Comparison */ @@ -144,7 +125,7 @@ class ExpressionBuilder /** * @param string $field - * @param mixed $values + * @param array $values * * @return Comparison */ @@ -170,7 +151,7 @@ class ExpressionBuilder * * @return Comparison */ - public function memberOf ($field, $value) + public function memberOf($field, $value) { return new Comparison($field, Comparison::MEMBER_OF, new Value($value)); } @@ -195,6 +176,5 @@ class ExpressionBuilder public function endsWith($field, $value) { return new Comparison($field, Comparison::ENDS_WITH, new Value($value)); - } - + } } diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php index 57660ed7f..0a038941b 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php @@ -1,21 +1,4 @@ . - */ namespace Doctrine\Common\Collections; @@ -31,8 +14,9 @@ namespace Doctrine\Common\Collections; * this API can implement efficient database access without having to ask the * EntityManager or Repositories. * - * @author Benjamin Eberlei - * @since 2.3 + * @phpstan-template TKey + * @psalm-template TKey as array-key + * @psalm-template T */ interface Selectable { @@ -40,9 +24,9 @@ interface Selectable * Selects all elements from a selectable that match the expression and * returns a new collection containing these elements. * - * @param Criteria $criteria - * * @return Collection + * + * @psalm-return Collection */ public function matching(Criteria $criteria); } diff --git a/vendor/doctrine/collections/psalm.xml.dist b/vendor/doctrine/collections/psalm.xml.dist new file mode 100644 index 000000000..8c5b066d5 --- /dev/null +++ b/vendor/doctrine/collections/psalm.xml.dist @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/doctrine/inflector/README.md b/vendor/doctrine/inflector/README.md index acb55a014..341f8b2a4 100644 --- a/vendor/doctrine/inflector/README.md +++ b/vendor/doctrine/inflector/README.md @@ -1,6 +1,8 @@ # Doctrine Inflector Doctrine Inflector is a small library that can perform string manipulations -with regard to upper-/lowercase and singular/plural forms of words. +with regard to uppercase/lowercase and singular/plural forms of words. -[![Build Status](https://travis-ci.org/doctrine/inflector.svg?branch=master)](https://travis-ci.org/doctrine/inflector) +[![Build Status](https://travis-ci.org/doctrine/inflector.svg)](https://travis-ci.org/doctrine/inflector) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/inflector/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/inflector/?branch=master) +[![Code Coverage](https://scrutinizer-ci.com/g/doctrine/inflector/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/inflector/?branch=master) diff --git a/vendor/doctrine/inflector/composer.json b/vendor/doctrine/inflector/composer.json index e06b64946..ab51ba0f9 100644 --- a/vendor/doctrine/inflector/composer.json +++ b/vendor/doctrine/inflector/composer.json @@ -1,9 +1,9 @@ { "name": "doctrine/inflector", "type": "library", - "description": "Common String Manipulations with regard to casing and singular/plural rules.", - "keywords": ["string", "inflection", "singularize", "pluralize"], - "homepage": "http://www.doctrine-project.org", + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "keywords": ["php", "strings", "words", "manipulation", "inflector", "inflection", "uppercase", "lowercase", "singular", "plural"], + "homepage": "https://www.doctrine-project.org/projects/inflector.html", "license": "MIT", "authors": [ {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, @@ -13,20 +13,30 @@ {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} ], "require": { - "php": "^7.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^6.2" + "doctrine/coding-standard": "^7.0", + "phpstan/phpstan": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-strict-rules": "^0.11", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "autoload": { - "psr-4": { "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" } + "psr-4": { + "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector", + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } }, "autoload-dev": { - "psr-4": { "Doctrine\\Tests\\Common\\Inflector\\": "tests/Doctrine/Common/Inflector" } + "psr-4": { + "Doctrine\\Tests\\Common\\Inflector\\": "tests/Doctrine/Tests/Common/Inflector", + "Doctrine\\Tests\\Inflector\\": "tests/Doctrine/Tests/Inflector" + } }, "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "2.0.x-dev" } } } diff --git a/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php b/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php index 3a951af8d..d00e56516 100644 --- a/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php +++ b/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php @@ -19,277 +19,97 @@ namespace Doctrine\Common\Inflector; +use Doctrine\Inflector\Inflector as InflectorObject; +use Doctrine\Inflector\InflectorFactory; +use Doctrine\Inflector\LanguageInflectorFactory; +use Doctrine\Inflector\Rules\Pattern; +use Doctrine\Inflector\Rules\Patterns; +use Doctrine\Inflector\Rules\Ruleset; +use Doctrine\Inflector\Rules\Substitution; +use Doctrine\Inflector\Rules\Substitutions; +use Doctrine\Inflector\Rules\Transformation; +use Doctrine\Inflector\Rules\Transformations; +use Doctrine\Inflector\Rules\Word; +use InvalidArgumentException; +use function array_keys; +use function array_map; +use function array_unshift; +use function array_values; +use function sprintf; +use function trigger_error; +use const E_USER_DEPRECATED; + /** - * Doctrine inflector has static methods for inflecting text. - * - * The methods in these classes are from several different sources collected - * across several different php projects and several different authors. The - * original author names and emails are not known. - * - * Pluralize & Singularize implementation are borrowed from CakePHP with some modifications. - * - * @link www.doctrine-project.org - * @since 1.0 - * @author Konsta Vesterinen - * @author Jonathan H. Wage + * @deprecated */ class Inflector { /** - * Plural inflector rules. - * - * @var array + * @var LanguageInflectorFactory|null */ - private static $plural = array( - 'rules' => array( - '/(s)tatus$/i' => '\1\2tatuses', - '/(quiz)$/i' => '\1zes', - '/^(ox)$/i' => '\1\2en', - '/([m|l])ouse$/i' => '\1ice', - '/(matr|vert|ind)(ix|ex)$/i' => '\1ices', - '/(x|ch|ss|sh)$/i' => '\1es', - '/([^aeiouy]|qu)y$/i' => '\1ies', - '/(hive|gulf)$/i' => '\1s', - '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', - '/sis$/i' => 'ses', - '/([ti])um$/i' => '\1a', - '/(p)erson$/i' => '\1eople', - '/(m)an$/i' => '\1en', - '/(c)hild$/i' => '\1hildren', - '/(f)oot$/i' => '\1eet', - '/(buffal|her|potat|tomat|volcan)o$/i' => '\1\2oes', - '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i', - '/us$/i' => 'uses', - '/(alias)$/i' => '\1es', - '/(analys|ax|cris|test|thes)is$/i' => '\1es', - '/s$/' => 's', - '/^$/' => '', - '/$/' => 's', - ), - 'uninflected' => array( - '.*[nrlm]ese', - '.*deer', - '.*fish', - '.*measles', - '.*ois', - '.*pox', - '.*sheep', - 'people', - 'cookie', - 'police', - ), - 'irregular' => array( - 'atlas' => 'atlases', - 'axe' => 'axes', - 'beef' => 'beefs', - 'brother' => 'brothers', - 'cafe' => 'cafes', - 'chateau' => 'chateaux', - 'niveau' => 'niveaux', - 'child' => 'children', - 'cookie' => 'cookies', - 'corpus' => 'corpuses', - 'cow' => 'cows', - 'criterion' => 'criteria', - 'curriculum' => 'curricula', - 'demo' => 'demos', - 'domino' => 'dominoes', - 'echo' => 'echoes', - 'foot' => 'feet', - 'fungus' => 'fungi', - 'ganglion' => 'ganglions', - 'genie' => 'genies', - 'genus' => 'genera', - 'graffito' => 'graffiti', - 'hippopotamus' => 'hippopotami', - 'hoof' => 'hoofs', - 'human' => 'humans', - 'iris' => 'irises', - 'larva' => 'larvae', - 'leaf' => 'leaves', - 'loaf' => 'loaves', - 'man' => 'men', - 'medium' => 'media', - 'memorandum' => 'memoranda', - 'money' => 'monies', - 'mongoose' => 'mongooses', - 'motto' => 'mottoes', - 'move' => 'moves', - 'mythos' => 'mythoi', - 'niche' => 'niches', - 'nucleus' => 'nuclei', - 'numen' => 'numina', - 'occiput' => 'occiputs', - 'octopus' => 'octopuses', - 'opus' => 'opuses', - 'ox' => 'oxen', - 'passerby' => 'passersby', - 'penis' => 'penises', - 'person' => 'people', - 'plateau' => 'plateaux', - 'runner-up' => 'runners-up', - 'sex' => 'sexes', - 'soliloquy' => 'soliloquies', - 'son-in-law' => 'sons-in-law', - 'syllabus' => 'syllabi', - 'testis' => 'testes', - 'thief' => 'thieves', - 'tooth' => 'teeth', - 'tornado' => 'tornadoes', - 'trilby' => 'trilbys', - 'turf' => 'turfs', - 'volcano' => 'volcanoes', - ) - ); + private static $factory; - /** - * Singular inflector rules. - * - * @var array - */ - private static $singular = array( - 'rules' => array( - '/(s)tatuses$/i' => '\1\2tatus', - '/^(.*)(menu)s$/i' => '\1\2', - '/(quiz)zes$/i' => '\\1', - '/(matr)ices$/i' => '\1ix', - '/(vert|ind)ices$/i' => '\1ex', - '/^(ox)en/i' => '\1', - '/(alias)(es)*$/i' => '\1', - '/(buffal|her|potat|tomat|volcan)oes$/i' => '\1o', - '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us', - '/([ftw]ax)es/i' => '\1', - '/(analys|ax|cris|test|thes)es$/i' => '\1is', - '/(shoe|slave)s$/i' => '\1', - '/(o)es$/i' => '\1', - '/ouses$/' => 'ouse', - '/([^a])uses$/' => '\1us', - '/([m|l])ice$/i' => '\1ouse', - '/(x|ch|ss|sh)es$/i' => '\1', - '/(m)ovies$/i' => '\1\2ovie', - '/(s)eries$/i' => '\1\2eries', - '/([^aeiouy]|qu)ies$/i' => '\1y', - '/([lr])ves$/i' => '\1f', - '/(tive)s$/i' => '\1', - '/(hive)s$/i' => '\1', - '/(drive)s$/i' => '\1', - '/(dive)s$/i' => '\1', - '/([^fo])ves$/i' => '\1fe', - '/(^analy)ses$/i' => '\1sis', - '/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', - '/([ti])a$/i' => '\1um', - '/(p)eople$/i' => '\1\2erson', - '/(m)en$/i' => '\1an', - '/(c)hildren$/i' => '\1\2hild', - '/(f)eet$/i' => '\1oot', - '/(n)ews$/i' => '\1\2ews', - '/eaus$/' => 'eau', - '/^(.*us)$/' => '\\1', - '/s$/i' => '', - ), - 'uninflected' => array( - '.*[nrlm]ese', - '.*deer', - '.*fish', - '.*measles', - '.*ois', - '.*pox', - '.*sheep', - '.*ss', - 'police', - 'pants', - 'clothes', - ), - 'irregular' => array( - 'caches' => 'cache', - 'criteria' => 'criterion', - 'curves' => 'curve', - 'emphases' => 'emphasis', - 'foes' => 'foe', - 'hoaxes' => 'hoax', - 'media' => 'medium', - 'neuroses' => 'neurosis', - 'waves' => 'wave', - 'oases' => 'oasis', - ) - ); + /** @var InflectorObject|null */ + private static $instance; - /** - * Words that should not be inflected. - * - * @var array - */ - private static $uninflected = array( - 'Amoyese', 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', - 'carp', 'chassis', 'clippers', 'cod', 'coitus', 'Congoese', 'contretemps', 'corps', - 'debris', 'diabetes', 'djinn', 'eland', 'elk', 'equipment', 'Faroese', 'flounder', - 'Foochowese', 'Furniture', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti', - 'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', - 'jackanapes', 'Kiplingese', 'Kongoese', 'Lucchese', 'Luggage', 'mackerel', 'Maltese', '.*?media', - 'mews', 'moose', 'mumps', 'Nankingese', 'news', 'nexus', 'Niasese', - 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', - 'proceedings', 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', - 'sea[- ]bass', 'series', 'Shavese', 'shears', 'siemens', 'species', 'staff', 'swine', - 'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese', 'whiting', - 'wildebeest', 'Yengeese' - ); + private static function getInstance() : InflectorObject + { + if (self::$factory === null) { + self::$factory = self::createFactory(); + } - /** - * Method cache array. - * - * @var array - */ - private static $cache = array(); + if (self::$instance === null) { + self::$instance = self::$factory->build(); + } - /** - * The initial state of Inflector so reset() works. - * - * @var array - */ - private static $initialState = array(); + return self::$instance; + } + + private static function createFactory() : LanguageInflectorFactory + { + return InflectorFactory::create(); + } /** * Converts a word into the format for a Doctrine table name. Converts 'ModelName' to 'model_name'. * - * @param string $word The word to tableize. - * - * @return string The tableized word. + * @deprecated */ - public static function tableize($word) + public static function tableize(string $word) : string { - return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $word)); + @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); + + return self::getInstance()->tableize($word); } /** * Converts a word into the format for a Doctrine class name. Converts 'table_name' to 'TableName'. - * - * @param string $word The word to classify. - * - * @return string The classified word. */ - public static function classify($word) + public static function classify(string $word) : string { - return str_replace(' ', '', ucwords(strtr($word, '_-', ' '))); + @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); + + return self::getInstance()->classify($word); } /** * Camelizes a word. This uses the classify() method and turns the first character to lowercase. * - * @param string $word The word to camelize. - * - * @return string The camelized word. + * @deprecated */ - public static function camelize($word) + public static function camelize(string $word) : string { - return lcfirst(self::classify($word)); + @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); + + return self::getInstance()->camelize($word); } /** - * Uppercases words with configurable delimeters between words. + * Uppercases words with configurable delimiters between words. * * Takes a string and capitalizes all of the words, like PHP's built-in - * ucwords function. This extends that behavior, however, by allowing the - * word delimeters to be configured, rather than only separating on + * ucwords function. This extends that behavior, however, by allowing the + * word delimiters to be configured, rather than only separating on * whitespace. * * Here is an example: @@ -307,38 +127,29 @@ class Inflector * @param string $string The string to operate on. * @param string $delimiters A list of word separators. * - * @return string The string with all delimeter-separated words capitalized. + * @return string The string with all delimiter-separated words capitalized. + * + * @deprecated */ - public static function ucwords($string, $delimiters = " \n\t\r\0\x0B-") + public static function ucwords(string $string, string $delimiters = " \n\t\r\0\x0B-") : string { - return preg_replace_callback( - '/[^' . preg_quote($delimiters, '/') . ']+/', - function($matches) { - return ucfirst($matches[0]); - }, - $string - ); + @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please use the "ucwords" function instead.', __METHOD__), E_USER_DEPRECATED); + + return ucwords($string, $delimiters); } /** * Clears Inflectors inflected value caches, and resets the inflection * rules to the initial values. * - * @return void + * @deprecated */ - public static function reset() + public static function reset() : void { - if (empty(self::$initialState)) { - self::$initialState = get_class_vars('Inflector'); + @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); - return; - } - - foreach (self::$initialState as $key => $val) { - if ($key != 'initialState') { - self::${$key} = $val; - } - } + self::$factory = null; + self::$instance = null; } /** @@ -355,42 +166,85 @@ class Inflector * )); * }}} * - * @param string $type The type of inflection, either 'plural' or 'singular' - * @param array $rules An array of rules to be added. - * @param boolean $reset If true, will unset default inflections for all - * new rules that are being defined in $rules. + * @param string $type The type of inflection, either 'plural' or 'singular' + * @param array|iterable $rules An array of rules to be added. + * @param boolean $reset If true, will unset default inflections for all + * new rules that are being defined in $rules. * * @return void + * + * @deprecated */ - public static function rules($type, $rules, $reset = false) + public static function rules(string $type, iterable $rules, bool $reset = false) : void { + @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); + + if (self::$factory === null) { + self::$factory = self::createFactory(); + } + + self::$instance = null; + + switch ($type) { + case 'singular': + self::$factory->withSingularRules(self::buildRuleset($rules), $reset); + break; + case 'plural': + self::$factory->withPluralRules(self::buildRuleset($rules), $reset); + break; + default: + throw new InvalidArgumentException(sprintf('Cannot define custom inflection rules for type "%s".', $type)); + } + } + + private static function buildRuleset(iterable $rules) : Ruleset + { + $regular = []; + $irregular = []; + $uninflected = []; + foreach ($rules as $rule => $pattern) { if ( ! is_array($pattern)) { + $regular[$rule] = $pattern; + continue; } - if ($reset) { - self::${$type}[$rule] = $pattern; - } else { - self::${$type}[$rule] = ($rule === 'uninflected') - ? array_merge($pattern, self::${$type}[$rule]) - : $pattern + self::${$type}[$rule]; - } - - unset($rules[$rule], self::${$type}['cache' . ucfirst($rule)]); - - if (isset(self::${$type}['merged'][$rule])) { - unset(self::${$type}['merged'][$rule]); - } - - if ($type === 'plural') { - self::$cache['pluralize'] = self::$cache['tableize'] = array(); - } elseif ($type === 'singular') { - self::$cache['singularize'] = array(); + switch ($rule) { + case 'uninflected': + $uninflected = $pattern; + break; + case 'irregular': + $irregular = $pattern; + break; + case 'rules': + $regular = $pattern; + break; } } - self::${$type}['rules'] = $rules + self::${$type}['rules']; + return new Ruleset( + new Transformations(...array_map( + static function (string $pattern, string $replacement) : Transformation { + return new Transformation(new Pattern($pattern), $replacement); + }, + array_keys($regular), + array_values($regular) + )), + new Patterns(...array_map( + static function (string $pattern) : Pattern { + return new Pattern($pattern); + }, + $uninflected + )), + new Substitutions(...array_map( + static function (string $word, string $to) : Substitution { + return new Substitution(new Word($word), new Word($to)); + }, + array_keys($irregular), + array_values($irregular) + )) + ); } /** @@ -399,45 +253,14 @@ class Inflector * @param string $word The word in singular form. * * @return string The word in plural form. + * + * @deprecated */ - public static function pluralize($word) + public static function pluralize(string $word) : string { - if (isset(self::$cache['pluralize'][$word])) { - return self::$cache['pluralize'][$word]; - } + @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); - if (!isset(self::$plural['merged']['irregular'])) { - self::$plural['merged']['irregular'] = self::$plural['irregular']; - } - - if (!isset(self::$plural['merged']['uninflected'])) { - self::$plural['merged']['uninflected'] = array_merge(self::$plural['uninflected'], self::$uninflected); - } - - if (!isset(self::$plural['cacheUninflected']) || !isset(self::$plural['cacheIrregular'])) { - self::$plural['cacheUninflected'] = '(?:' . implode('|', self::$plural['merged']['uninflected']) . ')'; - self::$plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$plural['merged']['irregular'])) . ')'; - } - - if (preg_match('/(.*)\\b(' . self::$plural['cacheIrregular'] . ')$/i', $word, $regs)) { - self::$cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$plural['merged']['irregular'][strtolower($regs[2])], 1); - - return self::$cache['pluralize'][$word]; - } - - if (preg_match('/^(' . self::$plural['cacheUninflected'] . ')$/i', $word, $regs)) { - self::$cache['pluralize'][$word] = $word; - - return $word; - } - - foreach (self::$plural['rules'] as $rule => $replacement) { - if (preg_match($rule, $word)) { - self::$cache['pluralize'][$word] = preg_replace($rule, $replacement, $word); - - return self::$cache['pluralize'][$word]; - } - } + return self::getInstance()->pluralize($word); } /** @@ -446,54 +269,13 @@ class Inflector * @param string $word The word in plural form. * * @return string The word in singular form. + * + * @deprecated */ - public static function singularize($word) + public static function singularize(string $word) : string { - if (isset(self::$cache['singularize'][$word])) { - return self::$cache['singularize'][$word]; - } + @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); - if (!isset(self::$singular['merged']['uninflected'])) { - self::$singular['merged']['uninflected'] = array_merge( - self::$singular['uninflected'], - self::$uninflected - ); - } - - if (!isset(self::$singular['merged']['irregular'])) { - self::$singular['merged']['irregular'] = array_merge( - self::$singular['irregular'], - array_flip(self::$plural['irregular']) - ); - } - - if (!isset(self::$singular['cacheUninflected']) || !isset(self::$singular['cacheIrregular'])) { - self::$singular['cacheUninflected'] = '(?:' . join('|', self::$singular['merged']['uninflected']) . ')'; - self::$singular['cacheIrregular'] = '(?:' . join('|', array_keys(self::$singular['merged']['irregular'])) . ')'; - } - - if (preg_match('/(.*)\\b(' . self::$singular['cacheIrregular'] . ')$/i', $word, $regs)) { - self::$cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$singular['merged']['irregular'][strtolower($regs[2])], 1); - - return self::$cache['singularize'][$word]; - } - - if (preg_match('/^(' . self::$singular['cacheUninflected'] . ')$/i', $word, $regs)) { - self::$cache['singularize'][$word] = $word; - - return $word; - } - - foreach (self::$singular['rules'] as $rule => $replacement) { - if (preg_match($rule, $word)) { - self::$cache['singularize'][$word] = preg_replace($rule, $replacement, $word); - - return self::$cache['singularize'][$word]; - } - } - - self::$cache['singularize'][$word] = $word; - - return $word; + return self::getInstance()->singularize($word); } } diff --git a/vendor/doctrine/lexer/README.md b/vendor/doctrine/lexer/README.md index 3a74c1c31..e1b419a69 100644 --- a/vendor/doctrine/lexer/README.md +++ b/vendor/doctrine/lexer/README.md @@ -1,5 +1,7 @@ # Doctrine Lexer +Build Status: [![Build Status](https://travis-ci.org/doctrine/lexer.svg?branch=master)](https://travis-ci.org/doctrine/lexer) + Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers. This lexer is used in Doctrine Annotations and in Doctrine ORM (DQL). diff --git a/vendor/doctrine/lexer/composer.json b/vendor/doctrine/lexer/composer.json index 6ea83543a..3432bae4a 100644 --- a/vendor/doctrine/lexer/composer.json +++ b/vendor/doctrine/lexer/composer.json @@ -17,10 +17,12 @@ {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} ], "require": { - "php": ">=5.3.2" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^4.5" + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan": "^0.11.8", + "phpunit/phpunit": "^8.2" }, "autoload": { "psr-4": { "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" } @@ -30,7 +32,10 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } + }, + "config": { + "sort-packages": true } } diff --git a/vendor/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php b/vendor/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php index 317ff69d6..385643a4a 100644 --- a/vendor/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php +++ b/vendor/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php @@ -1,31 +1,21 @@ . - */ + +declare(strict_types=1); namespace Doctrine\Common\Lexer; +use ReflectionClass; +use const PREG_SPLIT_DELIM_CAPTURE; +use const PREG_SPLIT_NO_EMPTY; +use const PREG_SPLIT_OFFSET_CAPTURE; +use function implode; +use function in_array; +use function preg_split; +use function sprintf; +use function substr; + /** * Base class for writing simple lexers, i.e. for creating small DSLs. - * - * @since 2.0 - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel */ abstract class AbstractLexer { @@ -47,36 +37,43 @@ abstract class AbstractLexer * * @var array */ - private $tokens = array(); + private $tokens = []; /** * Current lexer position in input string. * - * @var integer + * @var int */ private $position = 0; /** * Current peek of current lexer position. * - * @var integer + * @var int */ private $peek = 0; /** * The next token in the input. * - * @var array + * @var array|null */ public $lookahead; /** * The last matched/seen token. * - * @var array + * @var array|null */ public $token; + /** + * Composed regex for input parsing. + * + * @var string + */ + private $regex; + /** * Sets the input data to be tokenized. * @@ -90,7 +87,7 @@ abstract class AbstractLexer public function setInput($input) { $this->input = $input; - $this->tokens = array(); + $this->tokens = []; $this->reset(); $this->scan($input); @@ -104,9 +101,9 @@ abstract class AbstractLexer public function reset() { $this->lookahead = null; - $this->token = null; - $this->peek = 0; - $this->position = 0; + $this->token = null; + $this->peek = 0; + $this->position = 0; } /** @@ -122,7 +119,7 @@ abstract class AbstractLexer /** * Resets the lexer position on the input to the given position. * - * @param integer $position Position to place the lexical scanner. + * @param int $position Position to place the lexical scanner. * * @return void */ @@ -134,7 +131,7 @@ abstract class AbstractLexer /** * Retrieve the original lexer's input until a given position. * - * @param integer $position + * @param int $position * * @return string */ @@ -146,13 +143,13 @@ abstract class AbstractLexer /** * Checks whether a given token matches the current lookahead. * - * @param integer|string $token + * @param int|string $token * - * @return boolean + * @return bool */ public function isNextToken($token) { - return null !== $this->lookahead && $this->lookahead['type'] === $token; + return $this->lookahead !== null && $this->lookahead['type'] === $token; } /** @@ -160,23 +157,23 @@ abstract class AbstractLexer * * @param array $tokens * - * @return boolean + * @return bool */ public function isNextTokenAny(array $tokens) { - return null !== $this->lookahead && in_array($this->lookahead['type'], $tokens, true); + return $this->lookahead !== null && in_array($this->lookahead['type'], $tokens, true); } /** * Moves to the next token in the input string. * - * @return boolean + * @return bool */ public function moveNext() { - $this->peek = 0; - $this->token = $this->lookahead; - $this->lookahead = (isset($this->tokens[$this->position])) + $this->peek = 0; + $this->token = $this->lookahead; + $this->lookahead = isset($this->tokens[$this->position]) ? $this->tokens[$this->position++] : null; return $this->lookahead !== null; @@ -199,10 +196,10 @@ abstract class AbstractLexer /** * Checks if given value is identical to the given token. * - * @param mixed $value - * @param integer $token + * @param mixed $value + * @param int|string $token * - * @return boolean + * @return bool */ public function isA($value, $token) { @@ -218,9 +215,9 @@ abstract class AbstractLexer { if (isset($this->tokens[$this->position + $this->peek])) { return $this->tokens[$this->position + $this->peek++]; - } else { - return null; } + + return null; } /** @@ -230,8 +227,9 @@ abstract class AbstractLexer */ public function glimpse() { - $peek = $this->peek(); + $peek = $this->peek(); $this->peek = 0; + return $peek; } @@ -244,10 +242,8 @@ abstract class AbstractLexer */ protected function scan($input) { - static $regex; - - if ( ! isset($regex)) { - $regex = sprintf( + if (! isset($this->regex)) { + $this->regex = sprintf( '/(%s)|%s/%s', implode(')|(', $this->getCatchablePatterns()), implode('|', $this->getNonCatchablePatterns()), @@ -255,37 +251,37 @@ abstract class AbstractLexer ); } - $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE; - $matches = preg_split($regex, $input, -1, $flags); + $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE; + $matches = preg_split($this->regex, $input, -1, $flags); - if (false === $matches) { + if ($matches === false) { // Work around https://bugs.php.net/78122 - $matches = array(array($input, 0)); + $matches = [[$input, 0]]; } foreach ($matches as $match) { // Must remain before 'value' assignment since it can change content $type = $this->getType($match[0]); - $this->tokens[] = array( + $this->tokens[] = [ 'value' => $match[0], 'type' => $type, 'position' => $match[1], - ); + ]; } } /** * Gets the literal for a given token. * - * @param integer $token + * @param int|string $token * - * @return string + * @return int|string */ public function getLiteral($token) { - $className = get_class($this); - $reflClass = new \ReflectionClass($className); + $className = static::class; + $reflClass = new ReflectionClass($className); $constants = $reflClass->getConstants(); foreach ($constants as $name => $value) { @@ -304,7 +300,7 @@ abstract class AbstractLexer */ protected function getModifiers() { - return 'i'; + return 'iu'; } /** @@ -326,7 +322,7 @@ abstract class AbstractLexer * * @param string $value * - * @return integer + * @return int|string|null */ abstract protected function getType(&$value); } diff --git a/vendor/egulias/email-validator/CHANGELOG.md b/vendor/egulias/email-validator/CHANGELOG.md new file mode 100644 index 000000000..83fd62e02 --- /dev/null +++ b/vendor/egulias/email-validator/CHANGELOG.md @@ -0,0 +1,33 @@ +# EmailValidator v3 Changelog + +## New Features + +* Access to local part and domain part from EmailParser +* Validations outside of the scope of the RFC will be considered "extra" validations, thus opening the door for adding new; will live in their own folder "extra" (as requested in #248, #195, #183). + +## Breacking changes + +* PHP version upgraded to match Symfony's (as of 12/2020). +* DNSCheckValidation now fails for missing MX records. While the RFC argues that the existence of only A records to be valid, starting in v3 they will be considered invalid. +* Emails domain part are now intenteded to be RFC 1035 compliant, rendering previous valid emails (e.g example@examp&) invalid. + +## PHP versions upgrade policy +PHP version upgrade requirement will happen via MINOR (3.x) version upgrades of the library, following the adoption level by major frameworks. + +## Changes +* #235 +* #215 +* #130 +* #258 +* #188 +* #181 +* #217 +* #214 +* #249 +* #236 +* #257 +* #210 + +## Thanks +To contributors, be it with PRs, reporting issues or supporting otherwise. + diff --git a/vendor/egulias/email-validator/CONTRIBUTING.md b/vendor/egulias/email-validator/CONTRIBUTING.md new file mode 100644 index 000000000..7b79e1081 --- /dev/null +++ b/vendor/egulias/email-validator/CONTRIBUTING.md @@ -0,0 +1,153 @@ +# Contributing + +When contributing to this repository make sure to follow the Pull request process below. +Reduce to the minimum 3rd party dependencies. + +Please note we have a [code of conduct](#Code of Conduct), please follow it in all your interactions with the project. + +## Pull Request Process + +When doing a PR to v2 remember that you also have to do the PR port to v3, or tests confirming the bug is not reproducible. + +1. Supported version is v3. If you are fixing a bug in v2, please port to v3 +2. Use the title as a brief description of the changes +3. Describe the changes you are proposing + 1. If adding an extra validation state the benefits of adding it and the problem is solving + 2. Document in the readme, by adding it to the list +4. Provide appropiate tests for the code you are submitting: aim to keep the existing coverage percentage. +5. Add your Twitter handle (if you have) so we can thank you there. + +## License +By contributing, you agree that your contributions will be licensed under its MIT License. + +## Code of Conduct + +### Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +### Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +### Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +### Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +### Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at . +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +#### Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +#### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +#### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +#### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +#### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +### Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available +at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/vendor/egulias/email-validator/LICENSE b/vendor/egulias/email-validator/LICENSE index c34d2c197..1f0f2678a 100644 --- a/vendor/egulias/email-validator/LICENSE +++ b/vendor/egulias/email-validator/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2016 Eduardo Gulias Davis +Copyright (c) 2013-2021 Eduardo Gulias Davis Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/egulias/email-validator/composer.json b/vendor/egulias/email-validator/composer.json index a275696ab..d598d1b62 100644 --- a/vendor/egulias/email-validator/composer.json +++ b/vendor/egulias/email-validator/composer.json @@ -9,18 +9,18 @@ ], "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "3.0.x-dev" } }, "require": { - "php": ">=5.5", - "doctrine/lexer": "^1.0.1", - "symfony/polyfill-intl-idn": "^1.10" + "php": ">=7.2", + "doctrine/lexer": "^1.2", + "symfony/polyfill-intl-idn": "^1.15" }, "require-dev": { - "dominicsayers/isemail": "^3.0.7", - "phpunit/phpunit": "^4.8.36|^7.5.15", - "satooshi/php-coveralls": "^1.0.1" + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^8.5.8|^9.3.3", + "vimeo/psalm": "^4" }, "suggest": { "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" diff --git a/vendor/egulias/email-validator/src/EmailLexer.php b/vendor/egulias/email-validator/src/EmailLexer.php index 59dcd5876..41e9ea948 100644 --- a/vendor/egulias/email-validator/src/EmailLexer.php +++ b/vendor/egulias/email-validator/src/EmailLexer.php @@ -7,37 +7,52 @@ use Doctrine\Common\Lexer\AbstractLexer; class EmailLexer extends AbstractLexer { //ASCII values - const C_DEL = 127; - const C_NUL = 0; - const S_AT = 64; - const S_BACKSLASH = 92; - const S_DOT = 46; - const S_DQUOTE = 34; - const S_SQUOTE = 39; - const S_BACKTICK = 96; - const S_OPENPARENTHESIS = 49; - const S_CLOSEPARENTHESIS = 261; - const S_OPENBRACKET = 262; - const S_CLOSEBRACKET = 263; - const S_HYPHEN = 264; - const S_COLON = 265; - const S_DOUBLECOLON = 266; - const S_SP = 267; - const S_HTAB = 268; - const S_CR = 269; - const S_LF = 270; - const S_IPV6TAG = 271; - const S_LOWERTHAN = 272; - const S_GREATERTHAN = 273; - const S_COMMA = 274; - const S_SEMICOLON = 275; - const S_OPENQBRACKET = 276; - const S_CLOSEQBRACKET = 277; - const S_SLASH = 278; const S_EMPTY = null; + const C_NUL = 0; + const S_HTAB = 9; + const S_LF = 10; + const S_CR = 13; + const S_SP = 32; + const EXCLAMATION = 33; + const S_DQUOTE = 34; + const NUMBER_SIGN = 35; + const DOLLAR = 36; + const PERCENTAGE = 37; + const AMPERSAND = 38; + const S_SQUOTE = 39; + const S_OPENPARENTHESIS = 40; + const S_CLOSEPARENTHESIS = 41; + const ASTERISK = 42; + const S_PLUS = 43; + const S_COMMA = 44; + const S_HYPHEN = 45; + const S_DOT = 46; + const S_SLASH = 47; + const S_COLON = 58; + const S_SEMICOLON = 59; + const S_LOWERTHAN = 60; + const S_EQUAL = 61; + const S_GREATERTHAN = 62; + const QUESTIONMARK = 63; + const S_AT = 64; + const S_OPENBRACKET = 91; + const S_BACKSLASH = 92; + const S_CLOSEBRACKET = 93; + const CARET = 94; + const S_UNDERSCORE = 95; + const S_BACKTICK = 96; + const S_OPENCURLYBRACES = 123; + const S_PIPE = 124; + const S_CLOSECURLYBRACES = 125; + const S_TILDE = 126; + const C_DEL = 127; + const INVERT_QUESTIONMARK= 168; + const INVERT_EXCLAMATION = 173; const GENERIC = 300; - const CRLF = 301; + const S_IPV6TAG = 301; const INVALID = 302; + const CRLF = 1310; + const S_DOUBLECOLON = 5858; const ASCII_INVALID_FROM = 127; const ASCII_INVALID_TO = 199; @@ -47,6 +62,8 @@ class EmailLexer extends AbstractLexer * @var array */ protected $charValue = array( + '{' => self::S_OPENCURLYBRACES, + '}' => self::S_CLOSECURLYBRACES, '(' => self::S_OPENPARENTHESIS, ')' => self::S_CLOSEPARENTHESIS, '<' => self::S_LOWERTHAN, @@ -71,10 +88,23 @@ class EmailLexer extends AbstractLexer "\n" => self::S_LF, "\r\n" => self::CRLF, 'IPv6' => self::S_IPV6TAG, - '{' => self::S_OPENQBRACKET, - '}' => self::S_CLOSEQBRACKET, '' => self::S_EMPTY, '\0' => self::C_NUL, + '*' => self::ASTERISK, + '!' => self::EXCLAMATION, + '&' => self::AMPERSAND, + '^' => self::CARET, + '$' => self::DOLLAR, + '%' => self::PERCENTAGE, + '~' => self::S_TILDE, + '|' => self::S_PIPE, + '_' => self::S_UNDERSCORE, + '=' => self::S_EQUAL, + '+' => self::S_PLUS, + '¿' => self::INVERT_QUESTIONMARK, + '?' => self::QUESTIONMARK, + '#' => self::NUMBER_SIGN, + '¡' => self::INVERT_EXCLAMATION, ); /** @@ -94,7 +124,9 @@ class EmailLexer extends AbstractLexer * * @var array * + * @psalm-suppress NonInvariantDocblockPropertyType * @psalm-var array{value:string, type:null|int, position:int} + * @psalm-suppress NonInvariantDocblockPropertyType */ public $token; @@ -114,6 +146,16 @@ class EmailLexer extends AbstractLexer 'position' => 0, ]; + /** + * @var string + */ + private $accumulator = ''; + + /** + * @var bool + */ + private $hasToRecord = false; + public function __construct() { $this->previous = $this->token = self::$nullToken; @@ -173,10 +215,18 @@ class EmailLexer extends AbstractLexer */ public function moveNext() { + if ($this->hasToRecord && $this->previous === self::$nullToken) { + $this->accumulator .= $this->token['value']; + } + $this->previous = $this->token; $hasNext = parent::moveNext(); $this->token = $this->token ?: self::$nullToken; + if ($this->hasToRecord) { + $this->accumulator .= $this->token['value']; + } + return $hasNext; } @@ -188,7 +238,7 @@ class EmailLexer extends AbstractLexer protected function getCatchablePatterns() { return array( - '[a-zA-Z_]+[46]?', //ASCII and domain literal + '[a-zA-Z]+[46]?', //ASCII and domain literal '[^\x00-\x7F]', //UTF-8 '[0-9]+', '\r\n', @@ -205,7 +255,9 @@ class EmailLexer extends AbstractLexer */ protected function getNonCatchablePatterns() { - return array('[\xA0-\xff]+'); + return [ + '[\xA0-\xff]+', + ]; } /** @@ -217,28 +269,38 @@ class EmailLexer extends AbstractLexer */ protected function getType(&$value) { - if ($this->isNullType($value)) { + $encoded = $value; + + if (mb_detect_encoding($value, 'auto', true) !== 'UTF-8') { + $encoded = utf8_encode($value); + } + + if ($this->isValid($encoded)) { + return $this->charValue[$encoded]; + } + + if ($this->isNullType($encoded)) { return self::C_NUL; } - if ($this->isValid($value)) { - return $this->charValue[$value]; - } - - if ($this->isUTF8Invalid($value)) { + if ($this->isInvalidChar($encoded)) { $this->hasInvalidTokens = true; return self::INVALID; } + return self::GENERIC; } - /** - * @param string $value - * - * @return bool - */ - protected function isValid($value) + protected function isInvalidChar(string $value) : bool + { + if(preg_match("/[^\p{S}\p{C}\p{Cc}]+/iu", $value) ) { + return false; + } + return true; + } + + protected function isValid(string $value) : bool { if (isset($this->charValue[$value])) { return true; @@ -260,11 +322,7 @@ class EmailLexer extends AbstractLexer return false; } - /** - * @param string $value - * @return bool - */ - protected function isUTF8Invalid($value) + protected function isUTF8Invalid(string $value) : bool { if (preg_match('/\p{Cc}+/u', $value)) { return true; @@ -280,4 +338,24 @@ class EmailLexer extends AbstractLexer { return 'iu'; } + + public function getAccumulatedValues() : string + { + return $this->accumulator; + } + + public function startRecording() : void + { + $this->hasToRecord = true; + } + + public function stopRecording() : void + { + $this->hasToRecord = false; + } + + public function clearRecorded() : void + { + $this->accumulator = ''; + } } diff --git a/vendor/egulias/email-validator/src/EmailParser.php b/vendor/egulias/email-validator/src/EmailParser.php index 6b7bad669..c78f74a98 100644 --- a/vendor/egulias/email-validator/src/EmailParser.php +++ b/vendor/egulias/email-validator/src/EmailParser.php @@ -2,26 +2,19 @@ namespace Egulias\EmailValidator; -use Egulias\EmailValidator\Exception\ExpectingATEXT; -use Egulias\EmailValidator\Exception\NoLocalPart; -use Egulias\EmailValidator\Parser\DomainPart; +use Egulias\EmailValidator\EmailLexer; +use Egulias\EmailValidator\Result\Result; use Egulias\EmailValidator\Parser\LocalPart; +use Egulias\EmailValidator\Parser\DomainPart; +use Egulias\EmailValidator\Result\ValidEmail; +use Egulias\EmailValidator\Result\InvalidEmail; use Egulias\EmailValidator\Warning\EmailTooLong; +use Egulias\EmailValidator\Result\Reason\NoLocalPart; -/** - * EmailParser - * - * @author Eduardo Gulias Davis - */ -class EmailParser +class EmailParser extends Parser { const EMAIL_MAX_LENGTH = 254; - /** - * @var array - */ - protected $warnings = []; - /** * @var string */ @@ -31,104 +24,65 @@ class EmailParser * @var string */ protected $localPart = ''; - /** - * @var EmailLexer - */ - protected $lexer; - /** - * @var LocalPart - */ - protected $localPartParser; - - /** - * @var DomainPart - */ - protected $domainPartParser; - - public function __construct(EmailLexer $lexer) + public function parse(string $str) : Result { - $this->lexer = $lexer; - $this->localPartParser = new LocalPart($this->lexer); - $this->domainPartParser = new DomainPart($this->lexer); - } - - /** - * @param string $str - * @return array - */ - public function parse($str) - { - $this->lexer->setInput($str); - - if (!$this->hasAtToken()) { - throw new NoLocalPart(); - } - - - $this->localPartParser->parse($str); - $this->domainPartParser->parse($str); - - $this->setParts($str); - - if ($this->lexer->hasInvalidTokens()) { - throw new ExpectingATEXT(); - } - - return array('local' => $this->localPart, 'domain' => $this->domainPart); - } - - /** - * @return Warning\Warning[] - */ - public function getWarnings() - { - $localPartWarnings = $this->localPartParser->getWarnings(); - $domainPartWarnings = $this->domainPartParser->getWarnings(); - $this->warnings = array_merge($localPartWarnings, $domainPartWarnings); + $result = parent::parse($str); $this->addLongEmailWarning($this->localPart, $this->domainPart); - return $this->warnings; + return $result; + } + + protected function preLeftParsing(): Result + { + if (!$this->hasAtToken()) { + return new InvalidEmail(new NoLocalPart(), $this->lexer->token["value"]); + } + return new ValidEmail(); } - /** - * @return string - */ - public function getParsedDomainPart() + protected function parseLeftFromAt(): Result + { + return $this->processLocalPart(); + } + + protected function parseRightFromAt(): Result + { + return $this->processDomainPart(); + } + + private function processLocalPart() : Result + { + $localPartParser = new LocalPart($this->lexer); + $localPartResult = $localPartParser->parse(); + $this->localPart = $localPartParser->localPart(); + $this->warnings = array_merge($localPartParser->getWarnings(), $this->warnings); + + return $localPartResult; + } + + private function processDomainPart() : Result + { + $domainPartParser = new DomainPart($this->lexer); + $domainPartResult = $domainPartParser->parse(); + $this->domainPart = $domainPartParser->domainPart(); + $this->warnings = array_merge($domainPartParser->getWarnings(), $this->warnings); + + return $domainPartResult; + } + + public function getDomainPart() : string { return $this->domainPart; } - /** - * @param string $email - */ - protected function setParts($email) + public function getLocalPart() : string { - $parts = explode('@', $email); - $this->domainPart = $this->domainPartParser->getDomainPart(); - $this->localPart = $parts[0]; + return $this->localPart; } - /** - * @return bool - */ - protected function hasAtToken() - { - $this->lexer->moveNext(); - $this->lexer->moveNext(); - if ($this->lexer->token['type'] === EmailLexer::S_AT) { - return false; - } - - return true; - } - - /** - * @param string $localPart - * @param string $parsedDomainPart - */ - protected function addLongEmailWarning($localPart, $parsedDomainPart) + private function addLongEmailWarning(string $localPart, string $parsedDomainPart) : void { if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAIL_MAX_LENGTH) { $this->warnings[EmailTooLong::CODE] = new EmailTooLong(); diff --git a/vendor/egulias/email-validator/src/EmailValidator.php b/vendor/egulias/email-validator/src/EmailValidator.php index a30f21dcd..5a2e5c822 100644 --- a/vendor/egulias/email-validator/src/EmailValidator.php +++ b/vendor/egulias/email-validator/src/EmailValidator.php @@ -2,7 +2,7 @@ namespace Egulias\EmailValidator; -use Egulias\EmailValidator\Exception\InvalidEmail; +use Egulias\EmailValidator\Result\InvalidEmail; use Egulias\EmailValidator\Validation\EmailValidation; class EmailValidator @@ -15,12 +15,12 @@ class EmailValidator /** * @var Warning\Warning[] */ - protected $warnings = []; + private $warnings = []; /** - * @var InvalidEmail|null + * @var ?InvalidEmail */ - protected $error; + private $error; public function __construct() { @@ -32,7 +32,7 @@ class EmailValidator * @param EmailValidation $emailValidation * @return bool */ - public function isValid($email, EmailValidation $emailValidation) + public function isValid(string $email, EmailValidation $emailValidation) { $isValid = $emailValidation->isValid($email, $this->lexer); $this->warnings = $emailValidation->getWarnings(); diff --git a/vendor/egulias/email-validator/src/MessageIDParser.php b/vendor/egulias/email-validator/src/MessageIDParser.php new file mode 100644 index 000000000..9b029e143 --- /dev/null +++ b/vendor/egulias/email-validator/src/MessageIDParser.php @@ -0,0 +1,93 @@ +addLongEmailWarning($this->idLeft, $this->idRight); + + return $result; + } + + protected function preLeftParsing(): Result + { + if (!$this->hasAtToken()) { + return new InvalidEmail(new NoLocalPart(), $this->lexer->token["value"]); + } + return new ValidEmail(); + } + + protected function parseLeftFromAt(): Result + { + return $this->processIDLeft(); + } + + protected function parseRightFromAt(): Result + { + return $this->processIDRight(); + } + + private function processIDLeft() : Result + { + $localPartParser = new IDLeftPart($this->lexer); + $localPartResult = $localPartParser->parse(); + $this->idLeft = $localPartParser->localPart(); + $this->warnings = array_merge($localPartParser->getWarnings(), $this->warnings); + + return $localPartResult; + } + + private function processIDRight() : Result + { + $domainPartParser = new IDRightPart($this->lexer); + $domainPartResult = $domainPartParser->parse(); + $this->idRight = $domainPartParser->domainPart(); + $this->warnings = array_merge($domainPartParser->getWarnings(), $this->warnings); + + return $domainPartResult; + } + + public function getLeftPart() : string + { + return $this->idLeft; + } + + public function getRightPart() : string + { + return $this->idRight; + } + + private function addLongEmailWarning(string $localPart, string $parsedDomainPart) : void + { + if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAILID_MAX_LENGTH) { + $this->warnings[EmailTooLong::CODE] = new EmailTooLong(); + } + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Parser.php b/vendor/egulias/email-validator/src/Parser.php new file mode 100644 index 000000000..b1905f9ab --- /dev/null +++ b/vendor/egulias/email-validator/src/Parser.php @@ -0,0 +1,78 @@ +lexer = $lexer; + } + + public function parse(string $str) : Result + { + $this->lexer->setInput($str); + + if ($this->lexer->hasInvalidTokens()) { + return new InvalidEmail(new ExpectingATEXT("Invalid tokens found"), $this->lexer->token["value"]); + } + + $preParsingResult = $this->preLeftParsing(); + if ($preParsingResult->isInvalid()) { + return $preParsingResult; + } + + $localPartResult = $this->parseLeftFromAt(); + + if ($localPartResult->isInvalid()) { + return $localPartResult; + } + + $domainPartResult = $this->parseRightFromAt(); + + if ($domainPartResult->isInvalid()) { + return $domainPartResult; + } + + return new ValidEmail(); + } + + /** + * @return Warning\Warning[] + */ + public function getWarnings() : array + { + return $this->warnings; + } + + protected function hasAtToken() : bool + { + $this->lexer->moveNext(); + $this->lexer->moveNext(); + + return $this->lexer->token['type'] !== EmailLexer::S_AT; + } +} diff --git a/vendor/egulias/email-validator/src/Parser/Comment.php b/vendor/egulias/email-validator/src/Parser/Comment.php new file mode 100644 index 000000000..ffa61281f --- /dev/null +++ b/vendor/egulias/email-validator/src/Parser/Comment.php @@ -0,0 +1,103 @@ +lexer = $lexer; + $this->commentStrategy = $commentStrategy; + } + + public function parse() : Result + { + if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { + $this->openedParenthesis++; + if($this->noClosingParenthesis()) { + return new InvalidEmail(new UnclosedComment(), $this->lexer->token['value']); + } + } + + if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) { + return new InvalidEmail(new UnOpenedComment(), $this->lexer->token['value']); + } + + $this->warnings[WarningComment::CODE] = new WarningComment(); + + $moreTokens = true; + while ($this->commentStrategy->exitCondition($this->lexer, $this->openedParenthesis) && $moreTokens){ + + if ($this->lexer->isNextToken(EmailLexer::S_OPENPARENTHESIS)) { + $this->openedParenthesis++; + } + $this->warnEscaping(); + if($this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) { + $this->openedParenthesis--; + } + $moreTokens = $this->lexer->moveNext(); + } + + if($this->openedParenthesis >= 1) { + return new InvalidEmail(new UnclosedComment(), $this->lexer->token['value']); + } else if ($this->openedParenthesis < 0) { + return new InvalidEmail(new UnOpenedComment(), $this->lexer->token['value']); + } + + $finalValidations = $this->commentStrategy->endOfLoopValidations($this->lexer); + + $this->warnings = array_merge($this->warnings, $this->commentStrategy->getWarnings()); + + return $finalValidations; + } + + + /** + * @return bool + */ + private function warnEscaping() : bool + { + //Backslash found + if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) { + return false; + } + + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) { + return false; + } + + $this->warnings[QuotedPart::CODE] = + new QuotedPart($this->lexer->getPrevious()['type'], $this->lexer->token['type']); + return true; + + } + + private function noClosingParenthesis() : bool + { + try { + $this->lexer->find(EmailLexer::S_CLOSEPARENTHESIS); + return false; + } catch (\RuntimeException $e) { + return true; + } + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php b/vendor/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php new file mode 100644 index 000000000..c388efd65 --- /dev/null +++ b/vendor/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php @@ -0,0 +1,18 @@ +isNextToken(EmailLexer::S_DOT))){ // || !$internalLexer->moveNext()) { + return false; + } + + return true; + } + + public function endOfLoopValidations(EmailLexer $lexer) : Result + { + //test for end of string + if (!$lexer->isNextToken(EmailLexer::S_DOT)) { + return new InvalidEmail(new ExpectingATEXT('DOT not found near CLOSEPARENTHESIS'), $lexer->token['value']); + } + //add warning + //Address is valid within the message but cannot be used unmodified for the envelope + return new ValidEmail(); + } + + public function getWarnings(): array + { + return []; + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php b/vendor/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php new file mode 100644 index 000000000..73bc7b2bc --- /dev/null +++ b/vendor/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php @@ -0,0 +1,37 @@ +isNextToken(EmailLexer::S_AT); + } + + public function endOfLoopValidations(EmailLexer $lexer) : Result + { + if (!$lexer->isNextToken(EmailLexer::S_AT)) { + return new InvalidEmail(new ExpectingATEXT('ATEX is not expected after closing comments'), $lexer->token['value']); + } + $this->warnings[CFWSNearAt::CODE] = new CFWSNearAt(); + return new ValidEmail(); + } + + public function getWarnings(): array + { + return $this->warnings; + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Parser/DomainLiteral.php b/vendor/egulias/email-validator/src/Parser/DomainLiteral.php new file mode 100644 index 000000000..54a6fab9e --- /dev/null +++ b/vendor/egulias/email-validator/src/Parser/DomainLiteral.php @@ -0,0 +1,212 @@ +addTagWarnings(); + + $IPv6TAG = false; + $addressLiteral = ''; + + do { + if ($this->lexer->token['type'] === EmailLexer::C_NUL) { + return new InvalidEmail(new ExpectingDTEXT(), $this->lexer->token['value']); + } + + $this->addObsoleteWarnings(); + + if ($this->lexer->isNextTokenAny(array(EmailLexer::S_OPENBRACKET, EmailLexer::S_OPENBRACKET))) { + return new InvalidEmail(new ExpectingDTEXT(), $this->lexer->token['value']); + } + + if ($this->lexer->isNextTokenAny( + array(EmailLexer::S_HTAB, EmailLexer::S_SP, $this->lexer->token['type'] === EmailLexer::CRLF) + )) { + $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); + $this->parseFWS(); + } + + if ($this->lexer->isNextToken(EmailLexer::S_CR)) { + return new InvalidEmail(new CRNoLF(), $this->lexer->token['value']); + } + + if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH) { + return new InvalidEmail(new UnusualElements($this->lexer->token['value']), $this->lexer->token['value']); + } + if ($this->lexer->token['type'] === EmailLexer::S_IPV6TAG) { + $IPv6TAG = true; + } + + if ($this->lexer->token['type'] === EmailLexer::S_CLOSEBRACKET) { + break; + } + + $addressLiteral .= $this->lexer->token['value']; + + } while ($this->lexer->moveNext()); + + + //Encapsulate + $addressLiteral = str_replace('[', '', $addressLiteral); + $isAddressLiteralIPv4 = $this->checkIPV4Tag($addressLiteral); + + if (!$isAddressLiteralIPv4) { + return new ValidEmail(); + } else { + $addressLiteral = $this->convertIPv4ToIPv6($addressLiteral); + } + + if (!$IPv6TAG) { + $this->warnings[WarningDomainLiteral::CODE] = new WarningDomainLiteral(); + return new ValidEmail(); + } + + $this->warnings[AddressLiteral::CODE] = new AddressLiteral(); + + $this->checkIPV6Tag($addressLiteral); + + return new ValidEmail(); + } + + /** + * @param string $addressLiteral + * @param int $maxGroups + */ + public function checkIPV6Tag($addressLiteral, $maxGroups = 8) : void + { + $prev = $this->lexer->getPrevious(); + if ($prev['type'] === EmailLexer::S_COLON) { + $this->warnings[IPV6ColonEnd::CODE] = new IPV6ColonEnd(); + } + + $IPv6 = substr($addressLiteral, 5); + //Daniel Marschall's new IPv6 testing strategy + $matchesIP = explode(':', $IPv6); + $groupCount = count($matchesIP); + $colons = strpos($IPv6, '::'); + + if (count(preg_grep('/^[0-9A-Fa-f]{0,4}$/', $matchesIP, PREG_GREP_INVERT)) !== 0) { + $this->warnings[IPV6BadChar::CODE] = new IPV6BadChar(); + } + + if ($colons === false) { + // We need exactly the right number of groups + if ($groupCount !== $maxGroups) { + $this->warnings[IPV6GroupCount::CODE] = new IPV6GroupCount(); + } + return; + } + + if ($colons !== strrpos($IPv6, '::')) { + $this->warnings[IPV6DoubleColon::CODE] = new IPV6DoubleColon(); + return; + } + + if ($colons === 0 || $colons === (strlen($IPv6) - 2)) { + // RFC 4291 allows :: at the start or end of an address + //with 7 other groups in addition + ++$maxGroups; + } + + if ($groupCount > $maxGroups) { + $this->warnings[IPV6MaxGroups::CODE] = new IPV6MaxGroups(); + } elseif ($groupCount === $maxGroups) { + $this->warnings[IPV6Deprecated::CODE] = new IPV6Deprecated(); + } + } + + public function convertIPv4ToIPv6(string $addressLiteralIPv4) : string + { + $matchesIP = array(); + $IPv4Match = preg_match( + '/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/', + $addressLiteralIPv4, + $matchesIP); + + // Extract IPv4 part from the end of the address-literal (if there is one) + if ($IPv4Match > 0) { + $index = (int) strrpos($addressLiteralIPv4, $matchesIP[0]); + //There's a match but it is at the start + if ($index > 0) { + // Convert IPv4 part to IPv6 format for further testing + return substr($addressLiteralIPv4, 0, $index) . '0:0'; + } + } + + return $addressLiteralIPv4; + } + + /** + * @param string $addressLiteral + * + * @return bool + */ + protected function checkIPV4Tag($addressLiteral) : bool + { + $matchesIP = array(); + $IPv4Match = preg_match( + '/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/', + $addressLiteral, + $matchesIP); + + // Extract IPv4 part from the end of the address-literal (if there is one) + + if ($IPv4Match > 0) { + $index = strrpos($addressLiteral, $matchesIP[0]); + //There's a match but it is at the start + if ($index === 0) { + $this->warnings[AddressLiteral::CODE] = new AddressLiteral(); + return false; + } + } + + return true; + } + + private function addObsoleteWarnings() : void + { + if ($this->lexer->token['type'] === EmailLexer::INVALID || + $this->lexer->token['type'] === EmailLexer::C_DEL || + $this->lexer->token['type'] === EmailLexer::S_LF || + $this->lexer->token['type'] === EmailLexer::S_BACKSLASH + ) { + $this->warnings[ObsoleteDTEXT::CODE] = new ObsoleteDTEXT(); + } + } + + private function addTagWarnings() : void + { + if ($this->lexer->isNextToken(EmailLexer::S_COLON)) { + $this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart(); + } + if ($this->lexer->isNextToken(EmailLexer::S_IPV6TAG)) { + $lexer = clone $this->lexer; + $lexer->moveNext(); + if ($lexer->isNextToken(EmailLexer::S_DOUBLECOLON)) { + $this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart(); + } + } + } + +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Parser/DomainPart.php b/vendor/egulias/email-validator/src/Parser/DomainPart.php index 28a051081..4ca54f2d9 100644 --- a/vendor/egulias/email-validator/src/Parser/DomainPart.php +++ b/vendor/egulias/email-validator/src/Parser/DomainPart.php @@ -3,417 +3,310 @@ namespace Egulias\EmailValidator\Parser; use Egulias\EmailValidator\EmailLexer; -use Egulias\EmailValidator\Exception\CharNotAllowed; -use Egulias\EmailValidator\Exception\CommaInDomain; -use Egulias\EmailValidator\Exception\ConsecutiveAt; -use Egulias\EmailValidator\Exception\CRLFAtTheEnd; -use Egulias\EmailValidator\Exception\CRNoLF; -use Egulias\EmailValidator\Exception\DomainHyphened; -use Egulias\EmailValidator\Exception\DotAtEnd; -use Egulias\EmailValidator\Exception\DotAtStart; -use Egulias\EmailValidator\Exception\ExpectingATEXT; -use Egulias\EmailValidator\Exception\ExpectingDomainLiteralClose; -use Egulias\EmailValidator\Exception\ExpectingDTEXT; -use Egulias\EmailValidator\Exception\NoDomainPart; -use Egulias\EmailValidator\Exception\UnopenedComment; -use Egulias\EmailValidator\Warning\AddressLiteral; -use Egulias\EmailValidator\Warning\CFWSWithFWS; -use Egulias\EmailValidator\Warning\DeprecatedComment; -use Egulias\EmailValidator\Warning\DomainLiteral; -use Egulias\EmailValidator\Warning\DomainTooLong; -use Egulias\EmailValidator\Warning\IPV6BadChar; -use Egulias\EmailValidator\Warning\IPV6ColonEnd; -use Egulias\EmailValidator\Warning\IPV6ColonStart; -use Egulias\EmailValidator\Warning\IPV6Deprecated; -use Egulias\EmailValidator\Warning\IPV6DoubleColon; -use Egulias\EmailValidator\Warning\IPV6GroupCount; -use Egulias\EmailValidator\Warning\IPV6MaxGroups; -use Egulias\EmailValidator\Warning\LabelTooLong; -use Egulias\EmailValidator\Warning\ObsoleteDTEXT; use Egulias\EmailValidator\Warning\TLD; +use Egulias\EmailValidator\Result\Result; +use Egulias\EmailValidator\Result\ValidEmail; +use Egulias\EmailValidator\Result\InvalidEmail; +use Egulias\EmailValidator\Result\Reason\DotAtEnd; +use Egulias\EmailValidator\Result\Reason\DotAtStart; +use Egulias\EmailValidator\Warning\DeprecatedComment; +use Egulias\EmailValidator\Result\Reason\CRLFAtTheEnd; +use Egulias\EmailValidator\Result\Reason\LabelTooLong; +use Egulias\EmailValidator\Result\Reason\NoDomainPart; +use Egulias\EmailValidator\Result\Reason\ConsecutiveAt; +use Egulias\EmailValidator\Result\Reason\DomainTooLong; +use Egulias\EmailValidator\Result\Reason\CharNotAllowed; +use Egulias\EmailValidator\Result\Reason\DomainHyphened; +use Egulias\EmailValidator\Result\Reason\ExpectingATEXT; +use Egulias\EmailValidator\Parser\CommentStrategy\DomainComment; +use Egulias\EmailValidator\Result\Reason\ExpectingDomainLiteralClose; +use Egulias\EmailValidator\Parser\DomainLiteral as DomainLiteralParser; -class DomainPart extends Parser +class DomainPart extends PartParser { - const DOMAIN_MAX_LENGTH = 254; + const DOMAIN_MAX_LENGTH = 253; + const LABEL_MAX_LENGTH = 63; /** * @var string */ protected $domainPart = ''; - public function parse($domainPart) + /** + * @var string + */ + protected $label = ''; + + public function parse() : Result { + $this->lexer->clearRecorded(); + $this->lexer->startRecording(); + $this->lexer->moveNext(); - $this->performDomainStartChecks(); - - $domain = $this->doParseDomainPart(); - - $prev = $this->lexer->getPrevious(); - $length = strlen($domain); - - if ($prev['type'] === EmailLexer::S_DOT) { - throw new DotAtEnd(); + $domainChecks = $this->performDomainStartChecks(); + if ($domainChecks->isInvalid()) { + return $domainChecks; } - if ($prev['type'] === EmailLexer::S_HYPHEN) { - throw new DomainHyphened(); + + if ($this->lexer->token['type'] === EmailLexer::S_AT) { + return new InvalidEmail(new ConsecutiveAt(), $this->lexer->token['value']); } + + $result = $this->doParseDomainPart(); + if ($result->isInvalid()) { + return $result; + } + + $end = $this->checkEndOfDomain(); + if ($end->isInvalid()) { + return $end; + } + + $this->lexer->stopRecording(); + $this->domainPart = $this->lexer->getAccumulatedValues(); + + $length = strlen($this->domainPart); if ($length > self::DOMAIN_MAX_LENGTH) { - $this->warnings[DomainTooLong::CODE] = new DomainTooLong(); + return new InvalidEmail(new DomainTooLong(), $this->lexer->token['value']); } - if ($prev['type'] === EmailLexer::S_CR) { - throw new CRLFAtTheEnd(); - } - $this->domainPart = $domain; + + return new ValidEmail(); } - private function performDomainStartChecks() + private function checkEndOfDomain() : Result { - $this->checkInvalidTokensAfterAT(); - $this->checkEmptyDomain(); + $prev = $this->lexer->getPrevious(); + if ($prev['type'] === EmailLexer::S_DOT) { + return new InvalidEmail(new DotAtEnd(), $this->lexer->token['value']); + } + if ($prev['type'] === EmailLexer::S_HYPHEN) { + return new InvalidEmail(new DomainHyphened('Hypen found at the end of the domain'), $prev['value']); + } + + if ($this->lexer->token['type'] === EmailLexer::S_SP) { + return new InvalidEmail(new CRLFAtTheEnd(), $prev['value']); + } + return new ValidEmail(); + + } + + private function performDomainStartChecks() : Result + { + $invalidTokens = $this->checkInvalidTokensAfterAT(); + if ($invalidTokens->isInvalid()) { + return $invalidTokens; + } + + $missingDomain = $this->checkEmptyDomain(); + if ($missingDomain->isInvalid()) { + return $missingDomain; + } if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { $this->warnings[DeprecatedComment::CODE] = new DeprecatedComment(); - $this->parseDomainComments(); } + return new ValidEmail(); } - private function checkEmptyDomain() + private function checkEmptyDomain() : Result { $thereIsNoDomain = $this->lexer->token['type'] === EmailLexer::S_EMPTY || ($this->lexer->token['type'] === EmailLexer::S_SP && !$this->lexer->isNextToken(EmailLexer::GENERIC)); if ($thereIsNoDomain) { - throw new NoDomainPart(); + return new InvalidEmail(new NoDomainPart(), $this->lexer->token['value']); } + + return new ValidEmail(); } - private function checkInvalidTokensAfterAT() + private function checkInvalidTokensAfterAT() : Result { if ($this->lexer->token['type'] === EmailLexer::S_DOT) { - throw new DotAtStart(); + return new InvalidEmail(new DotAtStart(), $this->lexer->token['value']); } if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN) { - throw new DomainHyphened(); + return new InvalidEmail(new DomainHyphened('After AT'), $this->lexer->token['value']); } + return new ValidEmail(); } - /** - * @return string - */ - public function getDomainPart() + protected function parseComments(): Result { - return $this->domainPart; + $commentParser = new Comment($this->lexer, new DomainComment()); + $result = $commentParser->parse(); + $this->warnings = array_merge($this->warnings, $commentParser->getWarnings()); + + return $result; } - /** - * @param string $addressLiteral - * @param int $maxGroups - */ - public function checkIPV6Tag($addressLiteral, $maxGroups = 8) - { - $prev = $this->lexer->getPrevious(); - if ($prev['type'] === EmailLexer::S_COLON) { - $this->warnings[IPV6ColonEnd::CODE] = new IPV6ColonEnd(); - } - - $IPv6 = substr($addressLiteral, 5); - //Daniel Marschall's new IPv6 testing strategy - $matchesIP = explode(':', $IPv6); - $groupCount = count($matchesIP); - $colons = strpos($IPv6, '::'); - - if (count(preg_grep('/^[0-9A-Fa-f]{0,4}$/', $matchesIP, PREG_GREP_INVERT)) !== 0) { - $this->warnings[IPV6BadChar::CODE] = new IPV6BadChar(); - } - - if ($colons === false) { - // We need exactly the right number of groups - if ($groupCount !== $maxGroups) { - $this->warnings[IPV6GroupCount::CODE] = new IPV6GroupCount(); - } - return; - } - - if ($colons !== strrpos($IPv6, '::')) { - $this->warnings[IPV6DoubleColon::CODE] = new IPV6DoubleColon(); - return; - } - - if ($colons === 0 || $colons === (strlen($IPv6) - 2)) { - // RFC 4291 allows :: at the start or end of an address - //with 7 other groups in addition - ++$maxGroups; - } - - if ($groupCount > $maxGroups) { - $this->warnings[IPV6MaxGroups::CODE] = new IPV6MaxGroups(); - } elseif ($groupCount === $maxGroups) { - $this->warnings[IPV6Deprecated::CODE] = new IPV6Deprecated(); - } - } - - /** - * @return string - */ - protected function doParseDomainPart() + protected function doParseDomainPart() : Result { + $tldMissing = true; + $hasComments = false; $domain = ''; - $openedParenthesis = 0; do { $prev = $this->lexer->getPrevious(); - $this->checkNotAllowedChars($this->lexer->token); - - if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { - $this->parseComments(); - $openedParenthesis += $this->getOpenedParenthesis(); - $this->lexer->moveNext(); - $tmpPrev = $this->lexer->getPrevious(); - if ($tmpPrev['type'] === EmailLexer::S_CLOSEPARENTHESIS) { - $openedParenthesis--; - } + $notAllowedChars = $this->checkNotAllowedChars($this->lexer->token); + if ($notAllowedChars->isInvalid()) { + return $notAllowedChars; } - if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) { - if ($openedParenthesis === 0) { - throw new UnopenedComment(); - } else { - $openedParenthesis--; + + if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS || + $this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS ) { + $hasComments = true; + $commentsResult = $this->parseComments(); + + //Invalid comment parsing + if($commentsResult->isInvalid()) { + return $commentsResult; } } - $this->checkConsecutiveDots(); - $this->checkDomainPartExceptions($prev); - - if ($this->hasBrackets()) { - $this->parseDomainLiteral(); + $dotsResult = $this->checkConsecutiveDots(); + if ($dotsResult->isInvalid()) { + return $dotsResult; } - $this->checkLabelLength($prev); + if ($this->lexer->token['type'] === EmailLexer::S_OPENBRACKET) { + $literalResult = $this->parseDomainLiteral(); - if ($this->isFWS()) { - $this->parseFWS(); + $this->addTLDWarnings($tldMissing); + return $literalResult; + } + + $labelCheck = $this->checkLabelLength(); + if ($labelCheck->isInvalid()) { + return $labelCheck; + } + + $FwsResult = $this->parseFWS(); + if($FwsResult->isInvalid()) { + return $FwsResult; } $domain .= $this->lexer->token['value']; - $this->lexer->moveNext(); - if ($this->lexer->token['type'] === EmailLexer::S_SP) { - throw new CharNotAllowed(); + + if ($this->lexer->token['type'] === EmailLexer::S_DOT && $this->lexer->isNextToken(EmailLexer::GENERIC)) { + $tldMissing = false; } + + $exceptionsResult = $this->checkDomainPartExceptions($prev, $hasComments); + if ($exceptionsResult->isInvalid()) { + return $exceptionsResult; + } + $this->lexer->moveNext(); + } while (null !== $this->lexer->token['type']); - return $domain; + $labelCheck = $this->checkLabelLength(true); + if ($labelCheck->isInvalid()) { + return $labelCheck; + } + $this->addTLDWarnings($tldMissing); + + $this->domainPart = $domain; + return new ValidEmail(); } - private function checkNotAllowedChars(array $token) + private function checkNotAllowedChars(array $token) : Result { $notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true]; if (isset($notAllowed[$token['type']])) { - throw new CharNotAllowed(); + return new InvalidEmail(new CharNotAllowed(), $token['value']); } + return new ValidEmail(); } /** - * @return string|false + * @return Result */ - protected function parseDomainLiteral() + protected function parseDomainLiteral() : Result { - if ($this->lexer->isNextToken(EmailLexer::S_COLON)) { - $this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart(); - } - if ($this->lexer->isNextToken(EmailLexer::S_IPV6TAG)) { - $lexer = clone $this->lexer; - $lexer->moveNext(); - if ($lexer->isNextToken(EmailLexer::S_DOUBLECOLON)) { - $this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart(); - } + try { + $this->lexer->find(EmailLexer::S_CLOSEBRACKET); + } catch (\RuntimeException $e) { + return new InvalidEmail(new ExpectingDomainLiteralClose(), $this->lexer->token['value']); } - return $this->doParseDomainLiteral(); + $domainLiteralParser = new DomainLiteralParser($this->lexer); + $result = $domainLiteralParser->parse(); + $this->warnings = array_merge($this->warnings, $domainLiteralParser->getWarnings()); + return $result; } - /** - * @return string|false - */ - protected function doParseDomainLiteral() + protected function checkDomainPartExceptions(array $prev, bool $hasComments) : Result { - $IPv6TAG = false; - $addressLiteral = ''; - do { - if ($this->lexer->token['type'] === EmailLexer::C_NUL) { - throw new ExpectingDTEXT(); - } - - if ($this->lexer->token['type'] === EmailLexer::INVALID || - $this->lexer->token['type'] === EmailLexer::C_DEL || - $this->lexer->token['type'] === EmailLexer::S_LF - ) { - $this->warnings[ObsoleteDTEXT::CODE] = new ObsoleteDTEXT(); - } - - if ($this->lexer->isNextTokenAny(array(EmailLexer::S_OPENQBRACKET, EmailLexer::S_OPENBRACKET))) { - throw new ExpectingDTEXT(); - } - - if ($this->lexer->isNextTokenAny( - array(EmailLexer::S_HTAB, EmailLexer::S_SP, $this->lexer->token['type'] === EmailLexer::CRLF) - )) { - $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); - $this->parseFWS(); - } - - if ($this->lexer->isNextToken(EmailLexer::S_CR)) { - throw new CRNoLF(); - } - - if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH) { - $this->warnings[ObsoleteDTEXT::CODE] = new ObsoleteDTEXT(); - $addressLiteral .= $this->lexer->token['value']; - $this->lexer->moveNext(); - $this->validateQuotedPair(); - } - if ($this->lexer->token['type'] === EmailLexer::S_IPV6TAG) { - $IPv6TAG = true; - } - if ($this->lexer->token['type'] === EmailLexer::S_CLOSEQBRACKET) { - break; - } - - $addressLiteral .= $this->lexer->token['value']; - - } while ($this->lexer->moveNext()); - - $addressLiteral = str_replace('[', '', $addressLiteral); - $addressLiteral = $this->checkIPV4Tag($addressLiteral); - - if (false === $addressLiteral) { - return $addressLiteral; - } - - if (!$IPv6TAG) { - $this->warnings[DomainLiteral::CODE] = new DomainLiteral(); - return $addressLiteral; - } - - $this->warnings[AddressLiteral::CODE] = new AddressLiteral(); - - $this->checkIPV6Tag($addressLiteral); - - return $addressLiteral; - } - - /** - * @param string $addressLiteral - * - * @return string|false - */ - protected function checkIPV4Tag($addressLiteral) - { - $matchesIP = array(); - - // Extract IPv4 part from the end of the address-literal (if there is one) - if (preg_match( - '/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/', - $addressLiteral, - $matchesIP - ) > 0 - ) { - $index = strrpos($addressLiteral, $matchesIP[0]); - if ($index === 0) { - $this->warnings[AddressLiteral::CODE] = new AddressLiteral(); - return false; - } - // Convert IPv4 part to IPv6 format for further testing - $addressLiteral = substr($addressLiteral, 0, (int) $index) . '0:0'; - } - - return $addressLiteral; - } - - protected function checkDomainPartExceptions(array $prev) - { - $invalidDomainTokens = array( - EmailLexer::S_DQUOTE => true, - EmailLexer::S_SQUOTE => true, - EmailLexer::S_BACKTICK => true, - EmailLexer::S_SEMICOLON => true, - EmailLexer::S_GREATERTHAN => true, - EmailLexer::S_LOWERTHAN => true, - ); - - if (isset($invalidDomainTokens[$this->lexer->token['type']])) { - throw new ExpectingATEXT(); - } - - if ($this->lexer->token['type'] === EmailLexer::S_COMMA) { - throw new CommaInDomain(); - } - - if ($this->lexer->token['type'] === EmailLexer::S_AT) { - throw new ConsecutiveAt(); - } - - if ($this->lexer->token['type'] === EmailLexer::S_OPENQBRACKET && $prev['type'] !== EmailLexer::S_AT) { - throw new ExpectingATEXT(); + if ($this->lexer->token['type'] === EmailLexer::S_OPENBRACKET && $prev['type'] !== EmailLexer::S_AT) { + return new InvalidEmail(new ExpectingATEXT('OPENBRACKET not after AT'), $this->lexer->token['value']); } if ($this->lexer->token['type'] === EmailLexer::S_HYPHEN && $this->lexer->isNextToken(EmailLexer::S_DOT)) { - throw new DomainHyphened(); + return new InvalidEmail(new DomainHyphened('Hypen found near DOT'), $this->lexer->token['value']); } if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH && $this->lexer->isNextToken(EmailLexer::GENERIC)) { - throw new ExpectingATEXT(); + return new InvalidEmail(new ExpectingATEXT('Escaping following "ATOM"'), $this->lexer->token['value']); } + + return $this->validateTokens($hasComments); } - /** - * @return bool - */ - protected function hasBrackets() + protected function validateTokens(bool $hasComments) : Result { - if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) { - return false; + $validDomainTokens = array( + EmailLexer::GENERIC => true, + EmailLexer::S_HYPHEN => true, + EmailLexer::S_DOT => true, + ); + + if ($hasComments) { + $validDomainTokens[EmailLexer::S_OPENPARENTHESIS] = true; + $validDomainTokens[EmailLexer::S_CLOSEPARENTHESIS] = true; } - try { - $this->lexer->find(EmailLexer::S_CLOSEBRACKET); - } catch (\RuntimeException $e) { - throw new ExpectingDomainLiteralClose(); + if (!isset($validDomainTokens[$this->lexer->token['type']])) { + return new InvalidEmail(new ExpectingATEXT('Invalid token in domain: ' . $this->lexer->token['value']), $this->lexer->token['value']); } - return true; + return new ValidEmail(); } - protected function checkLabelLength(array $prev) + private function checkLabelLength(bool $isEndOfDomain = false) : Result { - if ($this->lexer->token['type'] === EmailLexer::S_DOT && - $prev['type'] === EmailLexer::GENERIC && - strlen($prev['value']) > 63 - ) { - $this->warnings[LabelTooLong::CODE] = new LabelTooLong(); + if ($this->lexer->token['type'] === EmailLexer::S_DOT || $isEndOfDomain) { + if ($this->isLabelTooLong($this->label)) { + return new InvalidEmail(new LabelTooLong(), $this->lexer->token['value']); + } + $this->label = ''; } + $this->label .= $this->lexer->token['value']; + return new ValidEmail(); } - protected function parseDomainComments() - { - $this->isUnclosedComment(); - while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) { - $this->warnEscaping(); - $this->lexer->moveNext(); - } - $this->lexer->moveNext(); - if ($this->lexer->isNextToken(EmailLexer::S_DOT)) { - throw new ExpectingATEXT(); + private function isLabelTooLong(string $label) : bool + { + if (preg_match('/[^\x00-\x7F]/', $label)) { + idn_to_ascii(utf8_decode($label), IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $idnaInfo); + return (bool) ($idnaInfo['errors'] & IDNA_ERROR_LABEL_TOO_LONG); } + return strlen($label) > self::LABEL_MAX_LENGTH; } - protected function addTLDWarnings() + private function addTLDWarnings(bool $isTLDMissing) : void { - if ($this->warnings[DomainLiteral::CODE]) { + if ($isTLDMissing) { $this->warnings[TLD::CODE] = new TLD(); } } -} + + public function domainPart() : string + { + return $this->domainPart; + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Parser/DoubleQuote.php b/vendor/egulias/email-validator/src/Parser/DoubleQuote.php new file mode 100644 index 000000000..19c098e85 --- /dev/null +++ b/vendor/egulias/email-validator/src/Parser/DoubleQuote.php @@ -0,0 +1,87 @@ +checkDQUOTE(); + if($validQuotedString->isInvalid()) return $validQuotedString; + + $special = array( + EmailLexer::S_CR => true, + EmailLexer::S_HTAB => true, + EmailLexer::S_LF => true + ); + + $invalid = array( + EmailLexer::C_NUL => true, + EmailLexer::S_HTAB => true, + EmailLexer::S_CR => true, + EmailLexer::S_LF => true + ); + $setSpecialsWarning = true; + + $this->lexer->moveNext(); + + while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && null !== $this->lexer->token['type']) { + if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) { + $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); + $setSpecialsWarning = false; + } + if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH && $this->lexer->isNextToken(EmailLexer::S_DQUOTE)) { + $this->lexer->moveNext(); + } + + $this->lexer->moveNext(); + + if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) { + return new InvalidEmail(new ExpectingATEXT("Expecting ATEXT between DQUOTE"), $this->lexer->token['value']); + } + } + + $prev = $this->lexer->getPrevious(); + + if ($prev['type'] === EmailLexer::S_BACKSLASH) { + $validQuotedString = $this->checkDQUOTE(); + if($validQuotedString->isInvalid()) return $validQuotedString; + } + + if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) { + return new InvalidEmail(new ExpectingATEXT("Expecting ATEXT between DQUOTE"), $this->lexer->token['value']); + } + + return new ValidEmail(); + } + + protected function checkDQUOTE() : Result + { + $previous = $this->lexer->getPrevious(); + + if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] === EmailLexer::GENERIC) { + $description = 'https://tools.ietf.org/html/rfc5322#section-3.2.4 - quoted string should be a unit'; + return new InvalidEmail(new ExpectingATEXT($description), $this->lexer->token['value']); + } + + try { + $this->lexer->find(EmailLexer::S_DQUOTE); + } catch (\Exception $e) { + return new InvalidEmail(new UnclosedQuotedString(), $this->lexer->token['value']); + } + $this->warnings[QuotedString::CODE] = new QuotedString($previous['value'], $this->lexer->token['value']); + + return new ValidEmail(); + } + +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Parser/FoldingWhiteSpace.php b/vendor/egulias/email-validator/src/Parser/FoldingWhiteSpace.php new file mode 100644 index 000000000..d32231e7b --- /dev/null +++ b/vendor/egulias/email-validator/src/Parser/FoldingWhiteSpace.php @@ -0,0 +1,82 @@ +isFWS()) { + return new ValidEmail(); + } + + $previous = $this->lexer->getPrevious(); + + $resultCRLF = $this->checkCRLFInFWS(); + if ($resultCRLF->isInvalid()) { + return $resultCRLF; + } + + if ($this->lexer->token['type'] === EmailLexer::S_CR) { + return new InvalidEmail(new CRNoLF(), $this->lexer->token['value']); + } + + if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] !== EmailLexer::S_AT) { + return new InvalidEmail(new AtextAfterCFWS(), $this->lexer->token['value']); + } + + if ($this->lexer->token['type'] === EmailLexer::S_LF || $this->lexer->token['type'] === EmailLexer::C_NUL) { + return new InvalidEmail(new ExpectingCTEXT(), $this->lexer->token['value']); + } + + if ($this->lexer->isNextToken(EmailLexer::S_AT) || $previous['type'] === EmailLexer::S_AT) { + $this->warnings[CFWSNearAt::CODE] = new CFWSNearAt(); + } else { + $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); + } + + return new ValidEmail(); + } + + protected function checkCRLFInFWS() : Result + { + if ($this->lexer->token['type'] !== EmailLexer::CRLF) { + return new ValidEmail(); + } + + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) { + return new InvalidEmail(new CRLFX2(), $this->lexer->token['value']); + } + + //this has no coverage. Condition is repeated from above one + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) { + return new InvalidEmail(new CRLFAtTheEnd(), $this->lexer->token['value']); + } + + return new ValidEmail(); + } + + protected function isFWS() : bool + { + if ($this->escaped()) { + return false; + } + + return $this->lexer->token['type'] === EmailLexer::S_SP || + $this->lexer->token['type'] === EmailLexer::S_HTAB || + $this->lexer->token['type'] === EmailLexer::S_CR || + $this->lexer->token['type'] === EmailLexer::S_LF || + $this->lexer->token['type'] === EmailLexer::CRLF; + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Parser/IDLeftPart.php b/vendor/egulias/email-validator/src/Parser/IDLeftPart.php new file mode 100644 index 000000000..abb4982b7 --- /dev/null +++ b/vendor/egulias/email-validator/src/Parser/IDLeftPart.php @@ -0,0 +1,16 @@ +lexer->token['value']); + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Parser/IDRightPart.php b/vendor/egulias/email-validator/src/Parser/IDRightPart.php new file mode 100644 index 000000000..bcf80dd0f --- /dev/null +++ b/vendor/egulias/email-validator/src/Parser/IDRightPart.php @@ -0,0 +1,29 @@ + true, + EmailLexer::S_SQUOTE => true, + EmailLexer::S_BACKTICK => true, + EmailLexer::S_SEMICOLON => true, + EmailLexer::S_GREATERTHAN => true, + EmailLexer::S_LOWERTHAN => true, + ); + + if (isset($invalidDomainTokens[$this->lexer->token['type']])) { + return new InvalidEmail(new ExpectingATEXT('Invalid token in domain: ' . $this->lexer->token['value']), $this->lexer->token['value']); + } + return new ValidEmail(); + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Parser/LocalPart.php b/vendor/egulias/email-validator/src/Parser/LocalPart.php index 3c21f34ac..d505c6183 100644 --- a/vendor/egulias/email-validator/src/Parser/LocalPart.php +++ b/vendor/egulias/email-validator/src/Parser/LocalPart.php @@ -2,144 +2,163 @@ namespace Egulias\EmailValidator\Parser; -use Egulias\EmailValidator\Exception\DotAtEnd; -use Egulias\EmailValidator\Exception\DotAtStart; use Egulias\EmailValidator\EmailLexer; -use Egulias\EmailValidator\Exception\ExpectingAT; -use Egulias\EmailValidator\Exception\ExpectingATEXT; -use Egulias\EmailValidator\Exception\UnclosedQuotedString; -use Egulias\EmailValidator\Exception\UnopenedComment; -use Egulias\EmailValidator\Warning\CFWSWithFWS; +use Egulias\EmailValidator\Result\Result; +use Egulias\EmailValidator\Result\ValidEmail; +use Egulias\EmailValidator\Result\InvalidEmail; use Egulias\EmailValidator\Warning\LocalTooLong; +use Egulias\EmailValidator\Result\Reason\DotAtEnd; +use Egulias\EmailValidator\Result\Reason\DotAtStart; +use Egulias\EmailValidator\Result\Reason\ConsecutiveDot; +use Egulias\EmailValidator\Result\Reason\ExpectingATEXT; +use Egulias\EmailValidator\Parser\CommentStrategy\LocalComment; -class LocalPart extends Parser +class LocalPart extends PartParser { - public function parse($localPart) + /** + * @var string + */ + private $localPart = ''; + + + public function parse() : Result { - $parseDQuote = true; - $closingQuote = false; - $openedParenthesis = 0; - $totalLength = 0; + $this->lexer->startRecording(); while ($this->lexer->token['type'] !== EmailLexer::S_AT && null !== $this->lexer->token['type']) { - if ($this->lexer->token['type'] === EmailLexer::S_DOT && null === $this->lexer->getPrevious()['type']) { - throw new DotAtStart(); + if ($this->hasDotAtStart()) { + return new InvalidEmail(new DotAtStart(), $this->lexer->token['value']); } - $closingQuote = $this->checkDQUOTE($closingQuote); - if ($closingQuote && $parseDQuote) { - $parseDQuote = $this->parseDoubleQuote(); - } + if ($this->lexer->token['type'] === EmailLexer::S_DQUOTE) { + $dquoteParsingResult = $this->parseDoubleQuote(); - if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { - $this->parseComments(); - $openedParenthesis += $this->getOpenedParenthesis(); - } - - if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) { - if ($openedParenthesis === 0) { - throw new UnopenedComment(); + //Invalid double quote parsing + if($dquoteParsingResult->isInvalid()) { + return $dquoteParsingResult; } - - $openedParenthesis--; } - $this->checkConsecutiveDots(); + if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS || + $this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS ) { + $commentsResult = $this->parseComments(); + + //Invalid comment parsing + if($commentsResult->isInvalid()) { + return $commentsResult; + } + } + + if ($this->lexer->token['type'] === EmailLexer::S_DOT && $this->lexer->isNextToken(EmailLexer::S_DOT)) { + return new InvalidEmail(new ConsecutiveDot(), $this->lexer->token['value']); + } if ($this->lexer->token['type'] === EmailLexer::S_DOT && $this->lexer->isNextToken(EmailLexer::S_AT) ) { - throw new DotAtEnd(); + return new InvalidEmail(new DotAtEnd(), $this->lexer->token['value']); } - $this->warnEscaping(); - $this->isInvalidToken($this->lexer->token, $closingQuote); - - if ($this->isFWS()) { - $this->parseFWS(); + $resultEscaping = $this->validateEscaping(); + if ($resultEscaping->isInvalid()) { + return $resultEscaping; + } + + $resultToken = $this->validateTokens(false); + if ($resultToken->isInvalid()) { + return $resultToken; + } + + $resultFWS = $this->parseLocalFWS(); + if($resultFWS->isInvalid()) { + return $resultFWS; } - $totalLength += strlen($this->lexer->token['value']); $this->lexer->moveNext(); } - if ($totalLength > LocalTooLong::LOCAL_PART_LENGTH) { + $this->lexer->stopRecording(); + $this->localPart = rtrim($this->lexer->getAccumulatedValues(), '@'); + if (strlen($this->localPart) > LocalTooLong::LOCAL_PART_LENGTH) { $this->warnings[LocalTooLong::CODE] = new LocalTooLong(); } + + return new ValidEmail(); } - /** - * @return bool - */ - protected function parseDoubleQuote() + protected function validateTokens(bool $hasComments) : Result { - $parseAgain = true; - $special = array( - EmailLexer::S_CR => true, - EmailLexer::S_HTAB => true, - EmailLexer::S_LF => true + $invalidTokens = array( + EmailLexer::S_COMMA => EmailLexer::S_COMMA, + EmailLexer::S_CLOSEBRACKET => EmailLexer::S_CLOSEBRACKET, + EmailLexer::S_OPENBRACKET => EmailLexer::S_OPENBRACKET, + EmailLexer::S_GREATERTHAN => EmailLexer::S_GREATERTHAN, + EmailLexer::S_LOWERTHAN => EmailLexer::S_LOWERTHAN, + EmailLexer::S_COLON => EmailLexer::S_COLON, + EmailLexer::S_SEMICOLON => EmailLexer::S_SEMICOLON, + EmailLexer::INVALID => EmailLexer::INVALID ); - - $invalid = array( - EmailLexer::C_NUL => true, - EmailLexer::S_HTAB => true, - EmailLexer::S_CR => true, - EmailLexer::S_LF => true - ); - $setSpecialsWarning = true; - - $this->lexer->moveNext(); - - while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && null !== $this->lexer->token['type']) { - $parseAgain = false; - if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) { - $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); - $setSpecialsWarning = false; - } - if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH && $this->lexer->isNextToken(EmailLexer::S_DQUOTE)) { - $this->lexer->moveNext(); - } - - $this->lexer->moveNext(); - - if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) { - throw new ExpectingATEXT(); - } + if (isset($invalidTokens[$this->lexer->token['type']])) { + return new InvalidEmail(new ExpectingATEXT('Invalid token found'), $this->lexer->token['value']); } + return new ValidEmail(); + } - $prev = $this->lexer->getPrevious(); + public function localPart() : string + { + return $this->localPart; + } - if ($prev['type'] === EmailLexer::S_BACKSLASH) { - if (!$this->checkDQUOTE(false)) { - throw new UnclosedQuotedString(); - } + private function parseLocalFWS() : Result + { + $foldingWS = new FoldingWhiteSpace($this->lexer); + $resultFWS = $foldingWS->parse(); + if ($resultFWS->isValid()) { + $this->warnings = array_merge($this->warnings, $foldingWS->getWarnings()); } + return $resultFWS; + } - if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) { - throw new ExpectingAT(); - } + private function hasDotAtStart() : bool + { + return $this->lexer->token['type'] === EmailLexer::S_DOT && null === $this->lexer->getPrevious()['type']; + } + + private function parseDoubleQuote() : Result + { + $dquoteParser = new DoubleQuote($this->lexer); + $parseAgain = $dquoteParser->parse(); + $this->warnings = array_merge($this->warnings, $dquoteParser->getWarnings()); return $parseAgain; } - /** - * @param bool $closingQuote - */ - protected function isInvalidToken(array $token, $closingQuote) + protected function parseComments(): Result { - $forbidden = array( - EmailLexer::S_COMMA, - EmailLexer::S_CLOSEBRACKET, - EmailLexer::S_OPENBRACKET, - EmailLexer::S_GREATERTHAN, - EmailLexer::S_LOWERTHAN, - EmailLexer::S_COLON, - EmailLexer::S_SEMICOLON, - EmailLexer::INVALID - ); - - if (in_array($token['type'], $forbidden) && !$closingQuote) { - throw new ExpectingATEXT(); + $commentParser = new Comment($this->lexer, new LocalComment()); + $result = $commentParser->parse(); + $this->warnings = array_merge($this->warnings, $commentParser->getWarnings()); + if($result->isInvalid()) { + return $result; } + return $result; } -} + + private function validateEscaping() : Result + { + //Backslash found + if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) { + return new ValidEmail(); + } + + if ($this->lexer->isNextToken(EmailLexer::GENERIC)) { + return new InvalidEmail(new ExpectingATEXT('Found ATOM after escaping'), $this->lexer->token['value']); + } + + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) { + return new ValidEmail(); + } + + return new ValidEmail(); + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Parser/PartParser.php b/vendor/egulias/email-validator/src/Parser/PartParser.php new file mode 100644 index 000000000..fd65fc560 --- /dev/null +++ b/vendor/egulias/email-validator/src/Parser/PartParser.php @@ -0,0 +1,63 @@ +lexer = $lexer; + } + + abstract public function parse() : Result; + + /** + * @return \Egulias\EmailValidator\Warning\Warning[] + */ + public function getWarnings() + { + return $this->warnings; + } + + protected function parseFWS() : Result + { + $foldingWS = new FoldingWhiteSpace($this->lexer); + $resultFWS = $foldingWS->parse(); + $this->warnings = array_merge($this->warnings, $foldingWS->getWarnings()); + return $resultFWS; + } + + protected function checkConsecutiveDots() : Result + { + if ($this->lexer->token['type'] === EmailLexer::S_DOT && $this->lexer->isNextToken(EmailLexer::S_DOT)) { + return new InvalidEmail(new ConsecutiveDot(), $this->lexer->token['value']); + } + + return new ValidEmail(); + } + + protected function escaped() : bool + { + $previous = $this->lexer->getPrevious(); + + return $previous && $previous['type'] === EmailLexer::S_BACKSLASH + && + $this->lexer->token['type'] !== EmailLexer::GENERIC; + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Result/InvalidEmail.php b/vendor/egulias/email-validator/src/Result/InvalidEmail.php new file mode 100644 index 000000000..3d85e154a --- /dev/null +++ b/vendor/egulias/email-validator/src/Result/InvalidEmail.php @@ -0,0 +1,46 @@ +token = $token; + $this->reason = $reason; + } + + public function isValid(): bool + { + return false; + } + + public function isInvalid(): bool + { + return true; + } + + public function description(): string + { + return $this->reason->description() . " in char " . $this->token; + } + + public function code(): int + { + return $this->reason->code(); + } + + public function reason() : Reason + { + return $this->reason; + } + +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Result/MultipleErrors.php b/vendor/egulias/email-validator/src/Result/MultipleErrors.php new file mode 100644 index 000000000..24bf5ff73 --- /dev/null +++ b/vendor/egulias/email-validator/src/Result/MultipleErrors.php @@ -0,0 +1,54 @@ +reasons[$reason->code()] = $reason; + } + + /** + * @return Reason[] + */ + public function getReasons() : array + { + return $this->reasons; + } + + public function reason() : Reason + { + return $this->reasons[0]; + } + + public function description() : string + { + $description = ''; + foreach($this->reasons as $reason) { + $description .= $reason->description() . PHP_EOL; + } + + return $description; + } + + public function code() : int + { + return 0; + } +} diff --git a/vendor/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php b/vendor/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php new file mode 100644 index 000000000..76015a2d9 --- /dev/null +++ b/vendor/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php @@ -0,0 +1,16 @@ +detailedDescription = $details; + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php b/vendor/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php new file mode 100644 index 000000000..55f44bbaf --- /dev/null +++ b/vendor/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php @@ -0,0 +1,16 @@ +exception = $exception; + + } + public function code() : int + { + return 999; + } + + public function description() : string + { + return $this->exception->getMessage(); + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php b/vendor/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php new file mode 100644 index 000000000..07ea8d238 --- /dev/null +++ b/vendor/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php @@ -0,0 +1,16 @@ +detailedDescription; + } +} diff --git a/vendor/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php b/vendor/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php new file mode 100644 index 000000000..64f5f7c3e --- /dev/null +++ b/vendor/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php @@ -0,0 +1,16 @@ +element = $element; + } + + public function code() : int + { + return 201; + } + + public function description() : string + { + return 'Unusual element found, wourld render invalid in majority of cases. Element found: ' . $this->element; + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Result/Result.php b/vendor/egulias/email-validator/src/Result/Result.php new file mode 100644 index 000000000..1e16bccac --- /dev/null +++ b/vendor/egulias/email-validator/src/Result/Result.php @@ -0,0 +1,27 @@ +reason = new ReasonSpoofEmail(); + parent::__construct($this->reason, ''); + } +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Result/ValidEmail.php b/vendor/egulias/email-validator/src/Result/ValidEmail.php new file mode 100644 index 000000000..4f3693a92 --- /dev/null +++ b/vendor/egulias/email-validator/src/Result/ValidEmail.php @@ -0,0 +1,27 @@ +error = new LocalOrReservedDomain(); + $this->error = new InvalidEmail(new LocalOrReservedDomain(), $host); return false; } return $this->checkDns($host); } - public function getError() + public function getError() : ?InvalidEmail { return $this->error; } - public function getWarnings() + public function getWarnings() : array { return $this->warnings; } @@ -112,31 +118,43 @@ class DNSCheckValidation implements EmailValidation * * @return bool True on success. */ - private function validateDnsRecords($host) + private function validateDnsRecords($host) : bool { - // Get all MX, A and AAAA DNS records for host - // Using @ as workaround to fix https://bugs.php.net/bug.php?id=73149 - $dnsRecords = @dns_get_record($host, DNS_MX + DNS_A + DNS_AAAA); + // A workaround to fix https://bugs.php.net/bug.php?id=73149 + /** @psalm-suppress InvalidArgument */ + set_error_handler( + static function (int $errorLevel, string $errorMessage): ?bool { + throw new \RuntimeException("Unable to get DNS record for the host: $errorMessage"); + } + ); + try { + // Get all MX, A and AAAA DNS records for host + $dnsRecords = dns_get_record($host, static::DNS_RECORD_TYPES_TO_CHECK); + } catch (\RuntimeException $exception) { + $this->error = new InvalidEmail(new UnableToGetDNSRecord(), ''); + + return false; + } finally { + restore_error_handler(); + } // No MX, A or AAAA DNS records - if (empty($dnsRecords)) { - $this->error = new NoDNSRecord(); + if ($dnsRecords === [] || $dnsRecords === false) { + $this->error = new InvalidEmail(new ReasonNoDNSRecord(), ''); return false; } // For each DNS record foreach ($dnsRecords as $dnsRecord) { if (!$this->validateMXRecord($dnsRecord)) { + // No MX records (fallback to A or AAAA records) + if (empty($this->mxRecords)) { + $this->warnings[NoDNSMXRecord::CODE] = new NoDNSMXRecord(); + } return false; } } - - // No MX records (fallback to A or AAAA records) - if (empty($this->mxRecords)) { - $this->warnings[NoDNSMXRecord::CODE] = new NoDNSMXRecord(); - } - return true; } @@ -147,7 +165,7 @@ class DNSCheckValidation implements EmailValidation * * @return bool True if valid. */ - private function validateMxRecord($dnsRecord) + private function validateMxRecord($dnsRecord) : bool { if ($dnsRecord['type'] !== 'MX') { return true; @@ -155,7 +173,7 @@ class DNSCheckValidation implements EmailValidation // "Null MX" record indicates the domain accepts no mail (https://tools.ietf.org/html/rfc7505) if (empty($dnsRecord['target']) || $dnsRecord['target'] === '.') { - $this->error = new DomainAcceptsNoMail(); + $this->error = new InvalidEmail(new DomainAcceptsNoMail(), ""); return false; } @@ -163,4 +181,4 @@ class DNSCheckValidation implements EmailValidation return true; } -} +} \ No newline at end of file diff --git a/vendor/egulias/email-validator/src/Validation/EmailValidation.php b/vendor/egulias/email-validator/src/Validation/EmailValidation.php index d5a015be5..1bcc0a70b 100644 --- a/vendor/egulias/email-validator/src/Validation/EmailValidation.php +++ b/vendor/egulias/email-validator/src/Validation/EmailValidation.php @@ -3,7 +3,7 @@ namespace Egulias\EmailValidator\Validation; use Egulias\EmailValidator\EmailLexer; -use Egulias\EmailValidator\Exception\InvalidEmail; +use Egulias\EmailValidator\Result\InvalidEmail; use Egulias\EmailValidator\Warning\Warning; interface EmailValidation @@ -16,19 +16,19 @@ interface EmailValidation * * @return bool */ - public function isValid($email, EmailLexer $emailLexer); + public function isValid(string $email, EmailLexer $emailLexer) : bool; /** * Returns the validation error. * * @return InvalidEmail|null */ - public function getError(); + public function getError() : ?InvalidEmail; /** * Returns the validation warnings. * * @return Warning[] */ - public function getWarnings(); + public function getWarnings() : array; } diff --git a/vendor/egulias/email-validator/src/Validation/Extra/SpoofCheckValidation.php b/vendor/egulias/email-validator/src/Validation/Extra/SpoofCheckValidation.php new file mode 100644 index 000000000..4972dbcef --- /dev/null +++ b/vendor/egulias/email-validator/src/Validation/Extra/SpoofCheckValidation.php @@ -0,0 +1,52 @@ +setChecks(Spoofchecker::SINGLE_SCRIPT); + + if ($checker->isSuspicious($email)) { + $this->error = new SpoofEmail(); + } + + return $this->error === null; + } + + /** + * @return InvalidEmail + */ + public function getError() : ?InvalidEmail + { + return $this->error; + } + + public function getWarnings() : array + { + return []; + } +} diff --git a/vendor/egulias/email-validator/src/Validation/MessageIDValidation.php b/vendor/egulias/email-validator/src/Validation/MessageIDValidation.php new file mode 100644 index 000000000..0e020433d --- /dev/null +++ b/vendor/egulias/email-validator/src/Validation/MessageIDValidation.php @@ -0,0 +1,51 @@ +parse($email); + $this->warnings = $parser->getWarnings(); + if ($result->isInvalid()) { + /** @psalm-suppress PropertyTypeCoercion */ + $this->error = $result; + return false; + } + } catch (\Exception $invalid) { + $this->error = new InvalidEmail(new ExceptionFound($invalid), ''); + return false; + } + + return true; + } + + public function getWarnings(): array + { + return $this->warnings; + } + + public function getError(): ?InvalidEmail + { + return $this->error; + } +} diff --git a/vendor/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php b/vendor/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php index feb224023..6debf22fd 100644 --- a/vendor/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php +++ b/vendor/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php @@ -3,13 +3,15 @@ namespace Egulias\EmailValidator\Validation; use Egulias\EmailValidator\EmailLexer; +use Egulias\EmailValidator\Result\InvalidEmail; use Egulias\EmailValidator\Validation\Exception\EmptyValidationList; +use Egulias\EmailValidator\Result\MultipleErrors; class MultipleValidationWithAnd implements EmailValidation { /** - * If one of validations gets failure skips all succeeding validation. - * This means MultipleErrors will only contain a single error which first found. + * If one of validations fails, the remaining validations will be skept. + * This means MultipleErrors will only contain a single error, the first found. */ const STOP_ON_ERROR = 0; @@ -56,60 +58,51 @@ class MultipleValidationWithAnd implements EmailValidation /** * {@inheritdoc} */ - public function isValid($email, EmailLexer $emailLexer) + public function isValid(string $email, EmailLexer $emailLexer) : bool { $result = true; - $errors = []; foreach ($this->validations as $validation) { $emailLexer->reset(); $validationResult = $validation->isValid($email, $emailLexer); $result = $result && $validationResult; $this->warnings = array_merge($this->warnings, $validation->getWarnings()); - $errors = $this->addNewError($validation->getError(), $errors); + if (!$validationResult) { + $this->processError($validation); + } if ($this->shouldStop($result)) { break; } } - if (!empty($errors)) { - $this->error = new MultipleErrors($errors); - } - return $result; } - /** - * @param \Egulias\EmailValidator\Exception\InvalidEmail|null $possibleError - * @param \Egulias\EmailValidator\Exception\InvalidEmail[] $errors - * - * @return \Egulias\EmailValidator\Exception\InvalidEmail[] - */ - private function addNewError($possibleError, array $errors) + private function initErrorStorage() : void { - if (null !== $possibleError) { - $errors[] = $possibleError; + if (null === $this->error) { + $this->error = new MultipleErrors(); } - - return $errors; } - /** - * @param bool $result - * - * @return bool - */ - private function shouldStop($result) + private function processError(EmailValidation $validation) : void + { + if (null !== $validation->getError()) { + $this->initErrorStorage(); + /** @psalm-suppress PossiblyNullReference */ + $this->error->addReason($validation->getError()->reason()); + } + } + + private function shouldStop(bool $result) : bool { return !$result && $this->mode === self::STOP_ON_ERROR; } /** * Returns the validation errors. - * - * @return MultipleErrors|null */ - public function getError() + public function getError() : ?InvalidEmail { return $this->error; } @@ -117,7 +110,7 @@ class MultipleValidationWithAnd implements EmailValidation /** * {@inheritdoc} */ - public function getWarnings() + public function getWarnings() : array { return $this->warnings; } diff --git a/vendor/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php b/vendor/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php index 6b31e5440..06885ed71 100644 --- a/vendor/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php +++ b/vendor/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php @@ -3,8 +3,8 @@ namespace Egulias\EmailValidator\Validation; use Egulias\EmailValidator\EmailLexer; -use Egulias\EmailValidator\Exception\InvalidEmail; -use Egulias\EmailValidator\Validation\Error\RFCWarnings; +use Egulias\EmailValidator\Result\InvalidEmail; +use Egulias\EmailValidator\Result\Reason\RFCWarnings; class NoRFCWarningsValidation extends RFCValidation { @@ -16,7 +16,7 @@ class NoRFCWarningsValidation extends RFCValidation /** * {@inheritdoc} */ - public function isValid($email, EmailLexer $emailLexer) + public function isValid(string $email, EmailLexer $emailLexer) : bool { if (!parent::isValid($email, $emailLexer)) { return false; @@ -26,7 +26,7 @@ class NoRFCWarningsValidation extends RFCValidation return true; } - $this->error = new RFCWarnings(); + $this->error = new InvalidEmail(new RFCWarnings(), ''); return false; } @@ -34,7 +34,7 @@ class NoRFCWarningsValidation extends RFCValidation /** * {@inheritdoc} */ - public function getError() + public function getError() : ?InvalidEmail { return $this->error ?: parent::getError(); } diff --git a/vendor/egulias/email-validator/src/Validation/RFCValidation.php b/vendor/egulias/email-validator/src/Validation/RFCValidation.php index 8781e0b62..e2c27bacc 100644 --- a/vendor/egulias/email-validator/src/Validation/RFCValidation.php +++ b/vendor/egulias/email-validator/src/Validation/RFCValidation.php @@ -4,7 +4,8 @@ namespace Egulias\EmailValidator\Validation; use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailParser; -use Egulias\EmailValidator\Exception\InvalidEmail; +use Egulias\EmailValidator\Result\InvalidEmail; +use Egulias\EmailValidator\Result\Reason\ExceptionFound; class RFCValidation implements EmailValidation { @@ -19,30 +20,35 @@ class RFCValidation implements EmailValidation private $warnings = []; /** - * @var InvalidEmail|null + * @var ?InvalidEmail */ private $error; - public function isValid($email, EmailLexer $emailLexer) + public function isValid(string $email, EmailLexer $emailLexer) : bool { $this->parser = new EmailParser($emailLexer); try { - $this->parser->parse((string)$email); - } catch (InvalidEmail $invalid) { - $this->error = $invalid; + $result = $this->parser->parse($email); + $this->warnings = $this->parser->getWarnings(); + if ($result->isInvalid()) { + /** @psalm-suppress PropertyTypeCoercion */ + $this->error = $result; + return false; + } + } catch (\Exception $invalid) { + $this->error = new InvalidEmail(new ExceptionFound($invalid), ''); return false; } - $this->warnings = $this->parser->getWarnings(); return true; } - public function getError() + public function getError() : ?InvalidEmail { return $this->error; } - public function getWarnings() + public function getWarnings() : array { return $this->warnings; } diff --git a/vendor/league/flysystem/CODE_OF_CONDUCT.md b/vendor/league/flysystem/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..89569c015 --- /dev/null +++ b/vendor/league/flysystem/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at info+flysystem@frankdejonge.nl. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/vendor/league/flysystem/composer.json b/vendor/league/flysystem/composer.json index b0a68ec4b..bd7434a87 100644 --- a/vendor/league/flysystem/composer.json +++ b/vendor/league/flysystem/composer.json @@ -21,12 +21,13 @@ } ], "require": { - "php": ">=5.5.9", - "ext-fileinfo": "*" + "php": "^7.2.5 || ^8.0", + "ext-fileinfo": "*", + "league/mime-type-detection": "^1.3" }, "require-dev": { - "phpspec/phpspec": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "phpunit/phpunit": "^5.7.26" + "phpspec/prophecy": "^1.11.1", + "phpunit/phpunit": "^8.5.8" }, "autoload": { "psr-4": { @@ -36,10 +37,7 @@ "autoload-dev": { "psr-4": { "League\\Flysystem\\Stub\\": "stub/" - }, - "files": [ - "tests/PHPUnitHacks.php" - ] + } }, "suggest": { "ext-fileinfo": "Required for MimeType", diff --git a/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php b/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php index 95a6b4d09..b232cdc4b 100644 --- a/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php +++ b/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php @@ -440,7 +440,13 @@ abstract class AbstractFtpAdapter extends AbstractAdapter $path = $base === '' ? $name : $base . $this->separator . $name; if ($type === 'dir') { - return compact('type', 'path'); + $result = compact('type', 'path'); + if ($this->enableTimestampsOnUnixListings) { + $timestamp = $this->normalizeUnixTimestamp($month, $day, $timeOrYear); + $result += compact('timestamp'); + } + + return $result; } $permissions = $this->normalizePermissions($permissions); @@ -639,10 +645,7 @@ abstract class AbstractFtpAdapter extends AbstractAdapter */ public function getConnection() { - $tries = 0; - - while ( ! $this->isConnected() && $tries < 3) { - $tries++; + if ( ! $this->isConnected()) { $this->disconnect(); $this->connect(); } @@ -694,4 +697,9 @@ abstract class AbstractFtpAdapter extends AbstractAdapter * @return bool */ abstract public function isConnected(); + + protected function escapePath($path) + { + return str_replace(['*', '[', ']'], ['\\*', '\\[', '\\]'], $path); + } } diff --git a/vendor/league/flysystem/src/Adapter/Ftp.php b/vendor/league/flysystem/src/Adapter/Ftp.php index dc89e4318..b00921071 100644 --- a/vendor/league/flysystem/src/Adapter/Ftp.php +++ b/vendor/league/flysystem/src/Adapter/Ftp.php @@ -2,7 +2,6 @@ namespace League\Flysystem\Adapter; -use ErrorException; use League\Flysystem\Adapter\Polyfill\StreamedCopyTrait; use League\Flysystem\AdapterInterface; use League\Flysystem\Config; @@ -130,6 +129,9 @@ class Ftp extends AbstractFtpAdapter */ public function connect() { + $tries = 3; + start_connecting: + if ($this->ssl) { $this->connection = @ftp_ssl_connect($this->getHost(), $this->getPort(), $this->getTimeout()); } else { @@ -137,6 +139,10 @@ class Ftp extends AbstractFtpAdapter } if ( ! $this->connection) { + $tries--; + + if ($tries > 0) goto start_connecting; + throw new ConnectionRuntimeException('Could not connect to host: ' . $this->getHost() . ', port:' . $this->getPort()); } @@ -394,7 +400,7 @@ class Ftp extends AbstractFtpAdapter return ['type' => 'dir', 'path' => $path]; } - $listing = $this->ftpRawlist('-A', str_replace('*', '\\*', $path)); + $listing = $this->ftpRawlist('-A', $path); if (empty($listing) || in_array('total 0', $listing, true)) { return false; @@ -490,8 +496,6 @@ class Ftp extends AbstractFtpAdapter */ protected function listDirectoryContents($directory, $recursive = true) { - $directory = str_replace('*', '\\*', $directory); - if ($recursive && $this->recurseManually) { return $this->listDirectoryContentsRecursive($directory); } @@ -560,6 +564,7 @@ class Ftp extends AbstractFtpAdapter if ($this->isPureFtpd) { $path = str_replace(' ', '\ ', $path); + $this->escapePath($path); } return ftp_rawlist($connection, $options . ' ' . $path); diff --git a/vendor/league/flysystem/src/Adapter/Ftpd.php b/vendor/league/flysystem/src/Adapter/Ftpd.php index d5349e475..7e71d19f6 100644 --- a/vendor/league/flysystem/src/Adapter/Ftpd.php +++ b/vendor/league/flysystem/src/Adapter/Ftpd.php @@ -12,13 +12,16 @@ class Ftpd extends Ftp if ($path === '') { return ['type' => 'dir', 'path' => '']; } + if (@ftp_chdir($this->getConnection(), $path) === true) { $this->setConnectionRoot(); return ['type' => 'dir', 'path' => $path]; } - if ( ! ($object = ftp_raw($this->getConnection(), 'STAT ' . $path)) || count($object) < 3) { + $object = ftp_raw($this->getConnection(), 'STAT ' . $this->escapePath($path)); + + if ( ! $object || count($object) < 3) { return false; } @@ -34,7 +37,7 @@ class Ftpd extends Ftp */ protected function listDirectoryContents($directory, $recursive = true) { - $listing = ftp_rawlist($this->getConnection(), $directory, $recursive); + $listing = ftp_rawlist($this->getConnection(), $this->escapePath($directory), $recursive); if ($listing === false || ( ! empty($listing) && substr($listing[0], 0, 5) === "ftpd:")) { return []; diff --git a/vendor/league/flysystem/src/Filesystem.php b/vendor/league/flysystem/src/Filesystem.php index 0ce24845a..59cc82ee4 100644 --- a/vendor/league/flysystem/src/Filesystem.php +++ b/vendor/league/flysystem/src/Filesystem.php @@ -74,7 +74,7 @@ class Filesystem implements FilesystemInterface */ public function writeStream($path, $resource, array $config = []) { - if ( ! is_resource($resource)) { + if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') { throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); } @@ -107,7 +107,7 @@ class Filesystem implements FilesystemInterface */ public function putStream($path, $resource, array $config = []) { - if ( ! is_resource($resource)) { + if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') { throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); } @@ -158,7 +158,7 @@ class Filesystem implements FilesystemInterface */ public function updateStream($path, $resource, array $config = []) { - if ( ! is_resource($resource)) { + if ( ! is_resource($resource) || get_resource_type($resource) !== 'stream') { throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); } diff --git a/vendor/league/flysystem/src/Util/MimeType.php b/vendor/league/flysystem/src/Util/MimeType.php index 1f1949ce0..35cba3fb8 100644 --- a/vendor/league/flysystem/src/Util/MimeType.php +++ b/vendor/league/flysystem/src/Util/MimeType.php @@ -2,241 +2,72 @@ namespace League\Flysystem\Util; -use ErrorException; -use finfo; +use League\MimeTypeDetection\FinfoMimeTypeDetector; +use League\MimeTypeDetection\GeneratedExtensionToMimeTypeMap; +use League\MimeTypeDetection\MimeTypeDetector; /** * @internal */ class MimeType { - protected static $extensionToMimeTypeMap = [ - 'hqx' => 'application/mac-binhex40', - 'cpt' => 'application/mac-compactpro', - 'csv' => 'text/csv', - 'bin' => 'application/octet-stream', - 'dms' => 'application/octet-stream', - 'lha' => 'application/octet-stream', - 'lzh' => 'application/octet-stream', - 'exe' => 'application/octet-stream', - 'class' => 'application/octet-stream', - 'psd' => 'application/x-photoshop', - 'so' => 'application/octet-stream', - 'sea' => 'application/octet-stream', - 'dll' => 'application/octet-stream', - 'oda' => 'application/oda', - 'pdf' => 'application/pdf', - 'ai' => 'application/pdf', - 'eps' => 'application/postscript', - 'epub' => 'application/epub+zip', - 'ps' => 'application/postscript', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'mif' => 'application/vnd.mif', - 'xls' => 'application/vnd.ms-excel', - 'xlt' => 'application/vnd.ms-excel', - 'xla' => 'application/vnd.ms-excel', - 'ppt' => 'application/powerpoint', - 'pot' => 'application/vnd.ms-powerpoint', - 'pps' => 'application/vnd.ms-powerpoint', - 'ppa' => 'application/vnd.ms-powerpoint', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', - 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', - 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', - 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', - 'potm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', - 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', - 'wbxml' => 'application/wbxml', - 'wmlc' => 'application/wmlc', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dxr' => 'application/x-director', - 'dvi' => 'application/x-dvi', - 'gtar' => 'application/x-gtar', - 'gz' => 'application/x-gzip', - 'gzip' => 'application/x-gzip', - 'php' => 'application/x-httpd-php', - 'php4' => 'application/x-httpd-php', - 'php3' => 'application/x-httpd-php', - 'phtml' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'js' => 'application/javascript', - 'swf' => 'application/x-shockwave-flash', - 'sit' => 'application/x-stuffit', - 'tar' => 'application/x-tar', - 'tgz' => 'application/x-tar', - 'z' => 'application/x-compress', - 'xhtml' => 'application/xhtml+xml', - 'xht' => 'application/xhtml+xml', - 'rdf' => 'application/rdf+xml', - 'zip' => 'application/x-zip', - 'rar' => 'application/x-rar', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mpga' => 'audio/mpeg', - 'mp2' => 'audio/mpeg', - 'mp3' => 'audio/mpeg', - 'aif' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'ram' => 'audio/x-pn-realaudio', - 'rm' => 'audio/x-pn-realaudio', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'ra' => 'audio/x-realaudio', - 'rv' => 'video/vnd.rn-realvideo', - 'wav' => 'audio/x-wav', - 'jpg' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpe' => 'image/jpeg', - 'png' => 'image/png', - 'gif' => 'image/gif', - 'bmp' => 'image/bmp', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'svg' => 'image/svg+xml', - 'css' => 'text/css', - 'html' => 'text/html', - 'htm' => 'text/html', - 'shtml' => 'text/html', - 'txt' => 'text/plain', - 'text' => 'text/plain', - 'log' => 'text/plain', - 'markdown' => 'text/markdown', - 'md' => 'text/markdown', - 'rtx' => 'text/richtext', - 'rtf' => 'text/rtf', - 'xml' => 'application/xml', - 'xsl' => 'application/xml', - 'dmn' => 'application/octet-stream', - 'bpmn' => 'application/octet-stream', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpe' => 'video/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'avi' => 'video/x-msvideo', - 'movie' => 'video/x-sgi-movie', - 'doc' => 'application/msword', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'docm' => 'application/vnd.ms-word.template.macroEnabled.12', - 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', - 'dot' => 'application/msword', - 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', - 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', - 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', - 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', - 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', - 'word' => 'application/msword', - 'xl' => 'application/excel', - 'eml' => 'message/rfc822', - 'json' => 'application/json', - 'pem' => 'application/x-x509-user-cert', - 'p10' => 'application/x-pkcs10', - 'p12' => 'application/x-pkcs12', - 'p7a' => 'application/x-pkcs7-signature', - 'p7c' => 'application/pkcs7-mime', - 'p7m' => 'application/pkcs7-mime', - 'p7r' => 'application/x-pkcs7-certreqresp', - 'p7s' => 'application/pkcs7-signature', - 'crt' => 'application/x-x509-ca-cert', - 'crl' => 'application/pkix-crl', - 'der' => 'application/x-x509-ca-cert', - 'kdb' => 'application/octet-stream', - 'pgp' => 'application/pgp', - 'gpg' => 'application/gpg-keys', - 'sst' => 'application/octet-stream', - 'csr' => 'application/octet-stream', - 'rsa' => 'application/x-pkcs7', - 'cer' => 'application/pkix-cert', - '3g2' => 'video/3gpp2', - '3gp' => 'video/3gp', - 'mp4' => 'video/mp4', - 'm4a' => 'audio/x-m4a', - 'f4v' => 'video/mp4', - 'webm' => 'video/webm', - 'aac' => 'audio/x-acc', - 'm4u' => 'application/vnd.mpegurl', - 'm3u' => 'text/plain', - 'xspf' => 'application/xspf+xml', - 'vlc' => 'application/videolan', - 'wmv' => 'video/x-ms-wmv', - 'au' => 'audio/x-au', - 'ac3' => 'audio/ac3', - 'flac' => 'audio/x-flac', - 'ogg' => 'audio/ogg', - 'kmz' => 'application/vnd.google-earth.kmz', - 'kml' => 'application/vnd.google-earth.kml+xml', - 'ics' => 'text/calendar', - 'zsh' => 'text/x-scriptzsh', - '7zip' => 'application/x-7z-compressed', - 'cdr' => 'application/cdr', - 'wma' => 'audio/x-ms-wma', - 'jar' => 'application/java-archive', - 'tex' => 'application/x-tex', - 'latex' => 'application/x-latex', - 'odt' => 'application/vnd.oasis.opendocument.text', - 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', - 'odp' => 'application/vnd.oasis.opendocument.presentation', - 'odg' => 'application/vnd.oasis.opendocument.graphics', - 'odc' => 'application/vnd.oasis.opendocument.chart', - 'odf' => 'application/vnd.oasis.opendocument.formula', - 'odi' => 'application/vnd.oasis.opendocument.image', - 'odm' => 'application/vnd.oasis.opendocument.text-master', - 'odb' => 'application/vnd.oasis.opendocument.database', - 'ott' => 'application/vnd.oasis.opendocument.text-template', - 'webp' => 'image/webp', - 'ico' => 'image/x-icon', - ]; + protected static $extensionToMimeTypeMap = GeneratedExtensionToMimeTypeMap::MIME_TYPES_FOR_EXTENSIONS; + protected static $detector; + + public static function useDetector(MimeTypeDetector $detector) + { + static::$detector = $detector; + } + + /** + * @return MimeTypeDetector + */ + protected static function detector() + { + if ( ! static::$detector instanceof MimeTypeDetector) { + static::$detector = new FinfoMimeTypeDetector(); + } + + return static::$detector; + } + /** * Detects MIME Type based on given content. * * @param mixed $content * - * @return string|null MIME Type or NULL if no mime type detected + * @return string MIME Type */ public static function detectByContent($content) { - if ( ! class_exists('finfo') || ! is_string($content)) { - return null; + if (is_string($content)) { + return static::detector()->detectMimeTypeFromBuffer($content); } - try { - $finfo = new finfo(FILEINFO_MIME_TYPE); - return $finfo->buffer($content) ?: null; - // @codeCoverageIgnoreStart - } catch (ErrorException $e) { - // This is caused by an array to string conversion error. - } - } // @codeCoverageIgnoreEnd + return 'text/plain'; + } /** * Detects MIME Type based on file extension. * * @param string $extension * - * @return string|null MIME Type or NULL if no extension detected + * @return string MIME Type */ public static function detectByFileExtension($extension) { - return isset(static::$extensionToMimeTypeMap[$extension]) - ? static::$extensionToMimeTypeMap[$extension] - : 'text/plain'; + return static::detector()->detectMimeTypeFromPath('artificial.' . $extension) ?: 'text/plain'; } /** * @param string $filename * - * @return string|null MIME Type or NULL if no extension detected + * @return string MIME Type */ public static function detectByFilename($filename) { - $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); - - return empty($extension) ? 'text/plain' : static::detectByFileExtension($extension); + return static::detector()->detectMimeTypeFromPath($filename) ?: 'text/plain'; } /** diff --git a/vendor/league/mime-type-detection/CHANGELOG.md b/vendor/league/mime-type-detection/CHANGELOG.md new file mode 100644 index 000000000..d9eab90da --- /dev/null +++ b/vendor/league/mime-type-detection/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +## 1.7.0 - 2021-01-18 + +### Added + +- Added a `bufferSampleSize` parameter to the `FinfoMimeTypeDetector` class that allows you to send a reduced content sample which costs less memory. + +## 1.6.0 - 2021-01-18 + +### Changes + +- Updated generated mime-type map diff --git a/vendor/league/mime-type-detection/LICENSE b/vendor/league/mime-type-detection/LICENSE new file mode 100644 index 000000000..7c1027d3e --- /dev/null +++ b/vendor/league/mime-type-detection/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013-2020 Frank de Jonge + +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/vendor/league/mime-type-detection/composer.json b/vendor/league/mime-type-detection/composer.json new file mode 100644 index 000000000..765b05c2d --- /dev/null +++ b/vendor/league/mime-type-detection/composer.json @@ -0,0 +1,33 @@ +{ + "name": "league/mime-type-detection", + "description": "Mime-type detection for Flysystem", + "license": "MIT", + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "scripts": { + "phpstan": "vendor/bin/phpstan analyse -l 6 src" + }, + "require": { + "php": "^7.2 || ^8.0", + "ext-fileinfo": "*" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.8 || ^9.3", + "phpstan/phpstan": "^0.12.68", + "friendsofphp/php-cs-fixer": "^2.18" + }, + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "config": { + "platform": { + "php": "7.2.0" + } + } +} diff --git a/vendor/league/mime-type-detection/src/EmptyExtensionToMimeTypeMap.php b/vendor/league/mime-type-detection/src/EmptyExtensionToMimeTypeMap.php new file mode 100644 index 000000000..fc0424161 --- /dev/null +++ b/vendor/league/mime-type-detection/src/EmptyExtensionToMimeTypeMap.php @@ -0,0 +1,13 @@ +extensions = $extensions ?: new GeneratedExtensionToMimeTypeMap(); + } + + public function detectMimeType(string $path, $contents): ?string + { + return $this->detectMimeTypeFromPath($path); + } + + public function detectMimeTypeFromPath(string $path): ?string + { + $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION)); + + return $this->extensions->lookupMimeType($extension); + } + + public function detectMimeTypeFromFile(string $path): ?string + { + return $this->detectMimeTypeFromPath($path); + } + + public function detectMimeTypeFromBuffer(string $contents): ?string + { + return null; + } +} diff --git a/vendor/league/mime-type-detection/src/ExtensionToMimeTypeMap.php b/vendor/league/mime-type-detection/src/ExtensionToMimeTypeMap.php new file mode 100644 index 000000000..1dad7bc1a --- /dev/null +++ b/vendor/league/mime-type-detection/src/ExtensionToMimeTypeMap.php @@ -0,0 +1,10 @@ +finfo = new finfo(FILEINFO_MIME_TYPE, $magicFile); + $this->extensionMap = $extensionMap ?: new GeneratedExtensionToMimeTypeMap(); + $this->bufferSampleSize = $bufferSampleSize; + } + + public function detectMimeType(string $path, $contents): ?string + { + $mimeType = is_string($contents) + ? (@$this->finfo->buffer($this->takeSample($contents)) ?: null) + : null; + + if ($mimeType !== null && ! in_array($mimeType, self::INCONCLUSIVE_MIME_TYPES)) { + return $mimeType; + } + + return $this->detectMimeTypeFromPath($path); + } + + public function detectMimeTypeFromPath(string $path): ?string + { + $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION)); + + return $this->extensionMap->lookupMimeType($extension); + } + + public function detectMimeTypeFromFile(string $path): ?string + { + return @$this->finfo->file($path) ?: null; + } + + public function detectMimeTypeFromBuffer(string $contents): ?string + { + return @$this->finfo->buffer($this->takeSample($contents)) ?: null; + } + + private function takeSample(string $contents): string + { + if ($this->bufferSampleSize === null) { + return $contents; + } + + return (string) substr($contents, 0, $this->bufferSampleSize); + } +} diff --git a/vendor/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php b/vendor/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php new file mode 100644 index 000000000..698e2761f --- /dev/null +++ b/vendor/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php @@ -0,0 +1,1209 @@ + 'application/vnd.1000minds.decision-model+xml', + '3dml' => 'text/vnd.in3d.3dml', + '3ds' => 'image/x-3ds', + '3g2' => 'video/3gpp2', + '3gp' => 'video/3gp', + '3gpp' => 'video/3gpp', + '3mf' => 'model/3mf', + '7z' => 'application/x-7z-compressed', + '7zip' => 'application/x-7z-compressed', + '123' => 'application/vnd.lotus-1-2-3', + 'aab' => 'application/x-authorware-bin', + 'aac' => 'audio/x-acc', + 'aam' => 'application/x-authorware-map', + 'aas' => 'application/x-authorware-seg', + 'abw' => 'application/x-abiword', + 'ac' => 'application/vnd.nokia.n-gage.ac+xml', + 'ac3' => 'audio/ac3', + 'acc' => 'application/vnd.americandynamics.acc', + 'ace' => 'application/x-ace-compressed', + 'acu' => 'application/vnd.acucobol', + 'acutc' => 'application/vnd.acucorp', + 'adp' => 'audio/adpcm', + 'aep' => 'application/vnd.audiograph', + 'afm' => 'application/x-font-type1', + 'afp' => 'application/vnd.ibm.modcap', + 'ahead' => 'application/vnd.ahead.space', + 'ai' => 'application/pdf', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'air' => 'application/vnd.adobe.air-application-installer-package+zip', + 'ait' => 'application/vnd.dvb.ait', + 'ami' => 'application/vnd.amiga.ami', + 'apk' => 'application/vnd.android.package-archive', + 'apng' => 'image/apng', + 'appcache' => 'text/cache-manifest', + 'application' => 'application/x-ms-application', + 'apr' => 'application/vnd.lotus-approach', + 'arc' => 'application/x-freearc', + 'arj' => 'application/x-arj', + 'asc' => 'application/pgp-signature', + 'asf' => 'video/x-ms-asf', + 'asm' => 'text/x-asm', + 'aso' => 'application/vnd.accpac.simply.aso', + 'asx' => 'video/x-ms-asf', + 'atc' => 'application/vnd.acucorp', + 'atom' => 'application/atom+xml', + 'atomcat' => 'application/atomcat+xml', + 'atomdeleted' => 'application/atomdeleted+xml', + 'atomsvc' => 'application/atomsvc+xml', + 'atx' => 'application/vnd.antix.game-component', + 'au' => 'audio/x-au', + 'avi' => 'video/x-msvideo', + 'avif' => 'image/avif', + 'aw' => 'application/applixware', + 'azf' => 'application/vnd.airzip.filesecure.azf', + 'azs' => 'application/vnd.airzip.filesecure.azs', + 'azv' => 'image/vnd.airzip.accelerator.azv', + 'azw' => 'application/vnd.amazon.ebook', + 'b16' => 'image/vnd.pco.b16', + 'bat' => 'application/x-msdownload', + 'bcpio' => 'application/x-bcpio', + 'bdf' => 'application/x-font-bdf', + 'bdm' => 'application/vnd.syncml.dm+wbxml', + 'bdoc' => 'application/x-bdoc', + 'bed' => 'application/vnd.realvnc.bed', + 'bh2' => 'application/vnd.fujitsu.oasysprs', + 'bin' => 'application/octet-stream', + 'blb' => 'application/x-blorb', + 'blorb' => 'application/x-blorb', + 'bmi' => 'application/vnd.bmi', + 'bmml' => 'application/vnd.balsamiq.bmml+xml', + 'bmp' => 'image/bmp', + 'book' => 'application/vnd.framemaker', + 'box' => 'application/vnd.previewsystems.box', + 'boz' => 'application/x-bzip2', + 'bpk' => 'application/octet-stream', + 'bpmn' => 'application/octet-stream', + 'bsp' => 'model/vnd.valve.source.compiled-map', + 'btif' => 'image/prs.btif', + 'buffer' => 'application/octet-stream', + 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', + 'c' => 'text/x-c', + 'c4d' => 'application/vnd.clonk.c4group', + 'c4f' => 'application/vnd.clonk.c4group', + 'c4g' => 'application/vnd.clonk.c4group', + 'c4p' => 'application/vnd.clonk.c4group', + 'c4u' => 'application/vnd.clonk.c4group', + 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', + 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', + 'cab' => 'application/vnd.ms-cab-compressed', + 'caf' => 'audio/x-caf', + 'cap' => 'application/vnd.tcpdump.pcap', + 'car' => 'application/vnd.curl.car', + 'cat' => 'application/vnd.ms-pki.seccat', + 'cb7' => 'application/x-cbr', + 'cba' => 'application/x-cbr', + 'cbr' => 'application/x-cbr', + 'cbt' => 'application/x-cbr', + 'cbz' => 'application/x-cbr', + 'cc' => 'text/x-c', + 'cco' => 'application/x-cocoa', + 'cct' => 'application/x-director', + 'ccxml' => 'application/ccxml+xml', + 'cdbcmsg' => 'application/vnd.contact.cmsg', + 'cdf' => 'application/x-netcdf', + 'cdfx' => 'application/cdfx+xml', + 'cdkey' => 'application/vnd.mediastation.cdkey', + 'cdmia' => 'application/cdmi-capability', + 'cdmic' => 'application/cdmi-container', + 'cdmid' => 'application/cdmi-domain', + 'cdmio' => 'application/cdmi-object', + 'cdmiq' => 'application/cdmi-queue', + 'cdr' => 'application/cdr', + 'cdx' => 'chemical/x-cdx', + 'cdxml' => 'application/vnd.chemdraw+xml', + 'cdy' => 'application/vnd.cinderella', + 'cer' => 'application/pkix-cert', + 'cfs' => 'application/x-cfs-compressed', + 'cgm' => 'image/cgm', + 'chat' => 'application/x-chat', + 'chm' => 'application/vnd.ms-htmlhelp', + 'chrt' => 'application/vnd.kde.kchart', + 'cif' => 'chemical/x-cif', + 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', + 'cil' => 'application/vnd.ms-artgalry', + 'cjs' => 'application/node', + 'cla' => 'application/vnd.claymore', + 'class' => 'application/octet-stream', + 'clkk' => 'application/vnd.crick.clicker.keyboard', + 'clkp' => 'application/vnd.crick.clicker.palette', + 'clkt' => 'application/vnd.crick.clicker.template', + 'clkw' => 'application/vnd.crick.clicker.wordbank', + 'clkx' => 'application/vnd.crick.clicker', + 'clp' => 'application/x-msclip', + 'cmc' => 'application/vnd.cosmocaller', + 'cmdf' => 'chemical/x-cmdf', + 'cml' => 'chemical/x-cml', + 'cmp' => 'application/vnd.yellowriver-custom-menu', + 'cmx' => 'image/x-cmx', + 'cod' => 'application/vnd.rim.cod', + 'coffee' => 'text/coffeescript', + 'com' => 'application/x-msdownload', + 'conf' => 'text/plain', + 'cpio' => 'application/x-cpio', + 'cpp' => 'text/x-c', + 'cpt' => 'application/mac-compactpro', + 'crd' => 'application/x-mscardfile', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', + 'crx' => 'application/x-chrome-extension', + 'cryptonote' => 'application/vnd.rig.cryptonote', + 'csh' => 'application/x-csh', + 'csl' => 'application/vnd.citationstyles.style+xml', + 'csml' => 'chemical/x-csml', + 'csp' => 'application/vnd.commonspace', + 'csr' => 'application/octet-stream', + 'css' => 'text/css', + 'cst' => 'application/x-director', + 'csv' => 'text/csv', + 'cu' => 'application/cu-seeme', + 'curl' => 'text/vnd.curl', + 'cww' => 'application/prs.cww', + 'cxt' => 'application/x-director', + 'cxx' => 'text/x-c', + 'dae' => 'model/vnd.collada+xml', + 'daf' => 'application/vnd.mobius.daf', + 'dart' => 'application/vnd.dart', + 'dataless' => 'application/vnd.fdsn.seed', + 'davmount' => 'application/davmount+xml', + 'dbf' => 'application/vnd.dbf', + 'dbk' => 'application/docbook+xml', + 'dcr' => 'application/x-director', + 'dcurl' => 'text/vnd.curl.dcurl', + 'dd2' => 'application/vnd.oma.dd2+xml', + 'ddd' => 'application/vnd.fujixerox.ddd', + 'ddf' => 'application/vnd.syncml.dmddf+xml', + 'dds' => 'image/vnd.ms-dds', + 'deb' => 'application/x-debian-package', + 'def' => 'text/plain', + 'deploy' => 'application/octet-stream', + 'der' => 'application/x-x509-ca-cert', + 'dfac' => 'application/vnd.dreamfactory', + 'dgc' => 'application/x-dgc-compressed', + 'dic' => 'text/x-c', + 'dir' => 'application/x-director', + 'dis' => 'application/vnd.mobius.dis', + 'disposition-notification' => 'message/disposition-notification', + 'dist' => 'application/octet-stream', + 'distz' => 'application/octet-stream', + 'djv' => 'image/vnd.djvu', + 'djvu' => 'image/vnd.djvu', + 'dll' => 'application/octet-stream', + 'dmg' => 'application/x-apple-diskimage', + 'dmn' => 'application/octet-stream', + 'dmp' => 'application/vnd.tcpdump.pcap', + 'dms' => 'application/octet-stream', + 'dna' => 'application/vnd.dna', + 'doc' => 'application/msword', + 'docm' => 'application/vnd.ms-word.template.macroEnabled.12', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dot' => 'application/msword', + 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'dp' => 'application/vnd.osgi.dp', + 'dpg' => 'application/vnd.dpgraph', + 'dra' => 'audio/vnd.dra', + 'drle' => 'image/dicom-rle', + 'dsc' => 'text/prs.lines.tag', + 'dssc' => 'application/dssc+der', + 'dtb' => 'application/x-dtbook+xml', + 'dtd' => 'application/xml-dtd', + 'dts' => 'audio/vnd.dts', + 'dtshd' => 'audio/vnd.dts.hd', + 'dump' => 'application/octet-stream', + 'dvb' => 'video/vnd.dvb.file', + 'dvi' => 'application/x-dvi', + 'dwd' => 'application/atsc-dwd+xml', + 'dwf' => 'model/vnd.dwf', + 'dwg' => 'image/vnd.dwg', + 'dxf' => 'image/vnd.dxf', + 'dxp' => 'application/vnd.spotfire.dxp', + 'dxr' => 'application/x-director', + 'ear' => 'application/java-archive', + 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', + 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', + 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', + 'ecma' => 'application/ecmascript', + 'edm' => 'application/vnd.novadigm.edm', + 'edx' => 'application/vnd.novadigm.edx', + 'efif' => 'application/vnd.picsel', + 'ei6' => 'application/vnd.pg.osasli', + 'elc' => 'application/octet-stream', + 'emf' => 'image/emf', + 'eml' => 'message/rfc822', + 'emma' => 'application/emma+xml', + 'emotionml' => 'application/emotionml+xml', + 'emz' => 'application/x-msmetafile', + 'eol' => 'audio/vnd.digital-winds', + 'eot' => 'application/vnd.ms-fontobject', + 'eps' => 'application/postscript', + 'epub' => 'application/epub+zip', + 'es' => 'application/ecmascript', + 'es3' => 'application/vnd.eszigno3+xml', + 'esa' => 'application/vnd.osgi.subsystem', + 'esf' => 'application/vnd.epson.esf', + 'et3' => 'application/vnd.eszigno3+xml', + 'etx' => 'text/x-setext', + 'eva' => 'application/x-eva', + 'evy' => 'application/x-envoy', + 'exe' => 'application/octet-stream', + 'exi' => 'application/exi', + 'exr' => 'image/aces', + 'ext' => 'application/vnd.novadigm.ext', + 'ez' => 'application/andrew-inset', + 'ez2' => 'application/vnd.ezpix-album', + 'ez3' => 'application/vnd.ezpix-package', + 'f' => 'text/x-fortran', + 'f4v' => 'video/mp4', + 'f77' => 'text/x-fortran', + 'f90' => 'text/x-fortran', + 'fbs' => 'image/vnd.fastbidsheet', + 'fcdt' => 'application/vnd.adobe.formscentral.fcdt', + 'fcs' => 'application/vnd.isac.fcs', + 'fdf' => 'application/vnd.fdf', + 'fdt' => 'application/fdt+xml', + 'fe_launch' => 'application/vnd.denovo.fcselayout-link', + 'fg5' => 'application/vnd.fujitsu.oasysgp', + 'fgd' => 'application/x-director', + 'fh' => 'image/x-freehand', + 'fh4' => 'image/x-freehand', + 'fh5' => 'image/x-freehand', + 'fh7' => 'image/x-freehand', + 'fhc' => 'image/x-freehand', + 'fig' => 'application/x-xfig', + 'fits' => 'image/fits', + 'flac' => 'audio/x-flac', + 'fli' => 'video/x-fli', + 'flo' => 'application/vnd.micrografx.flo', + 'flv' => 'video/x-flv', + 'flw' => 'application/vnd.kde.kivio', + 'flx' => 'text/vnd.fmi.flexstor', + 'fly' => 'text/vnd.fly', + 'fm' => 'application/vnd.framemaker', + 'fnc' => 'application/vnd.frogans.fnc', + 'fo' => 'application/vnd.software602.filler.form+xml', + 'for' => 'text/x-fortran', + 'fpx' => 'image/vnd.fpx', + 'frame' => 'application/vnd.framemaker', + 'fsc' => 'application/vnd.fsc.weblaunch', + 'fst' => 'image/vnd.fst', + 'ftc' => 'application/vnd.fluxtime.clip', + 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', + 'fvt' => 'video/vnd.fvt', + 'fxp' => 'application/vnd.adobe.fxp', + 'fxpl' => 'application/vnd.adobe.fxp', + 'fzs' => 'application/vnd.fuzzysheet', + 'g2w' => 'application/vnd.geoplan', + 'g3' => 'image/g3fax', + 'g3w' => 'application/vnd.geospace', + 'gac' => 'application/vnd.groove-account', + 'gam' => 'application/x-tads', + 'gbr' => 'application/rpki-ghostbusters', + 'gca' => 'application/x-gca-compressed', + 'gdl' => 'model/vnd.gdl', + 'gdoc' => 'application/vnd.google-apps.document', + 'geo' => 'application/vnd.dynageo', + 'geojson' => 'application/geo+json', + 'gex' => 'application/vnd.geometry-explorer', + 'ggb' => 'application/vnd.geogebra.file', + 'ggt' => 'application/vnd.geogebra.tool', + 'ghf' => 'application/vnd.groove-help', + 'gif' => 'image/gif', + 'gim' => 'application/vnd.groove-identity-message', + 'glb' => 'model/gltf-binary', + 'gltf' => 'model/gltf+json', + 'gml' => 'application/gml+xml', + 'gmx' => 'application/vnd.gmx', + 'gnumeric' => 'application/x-gnumeric', + 'gpg' => 'application/gpg-keys', + 'gph' => 'application/vnd.flographit', + 'gpx' => 'application/gpx+xml', + 'gqf' => 'application/vnd.grafeq', + 'gqs' => 'application/vnd.grafeq', + 'gram' => 'application/srgs', + 'gramps' => 'application/x-gramps-xml', + 'gre' => 'application/vnd.geometry-explorer', + 'grv' => 'application/vnd.groove-injector', + 'grxml' => 'application/srgs+xml', + 'gsf' => 'application/x-font-ghostscript', + 'gsheet' => 'application/vnd.google-apps.spreadsheet', + 'gslides' => 'application/vnd.google-apps.presentation', + 'gtar' => 'application/x-gtar', + 'gtm' => 'application/vnd.groove-tool-message', + 'gtw' => 'model/vnd.gtw', + 'gv' => 'text/vnd.graphviz', + 'gxf' => 'application/gxf', + 'gxt' => 'application/vnd.geonext', + 'gz' => 'application/x-gzip', + 'gzip' => 'application/x-gzip', + 'h' => 'text/x-c', + 'h261' => 'video/h261', + 'h263' => 'video/h263', + 'h264' => 'video/h264', + 'hal' => 'application/vnd.hal+xml', + 'hbci' => 'application/vnd.hbci', + 'hbs' => 'text/x-handlebars-template', + 'hdd' => 'application/x-virtualbox-hdd', + 'hdf' => 'application/x-hdf', + 'heic' => 'image/heic', + 'heics' => 'image/heic-sequence', + 'heif' => 'image/heif', + 'heifs' => 'image/heif-sequence', + 'hej2' => 'image/hej2k', + 'held' => 'application/atsc-held+xml', + 'hh' => 'text/x-c', + 'hjson' => 'application/hjson', + 'hlp' => 'application/winhlp', + 'hpgl' => 'application/vnd.hp-hpgl', + 'hpid' => 'application/vnd.hp-hpid', + 'hps' => 'application/vnd.hp-hps', + 'hqx' => 'application/mac-binhex40', + 'hsj2' => 'image/hsj2', + 'htc' => 'text/x-component', + 'htke' => 'application/vnd.kenameaapp', + 'htm' => 'text/html', + 'html' => 'text/html', + 'hvd' => 'application/vnd.yamaha.hv-dic', + 'hvp' => 'application/vnd.yamaha.hv-voice', + 'hvs' => 'application/vnd.yamaha.hv-script', + 'i2g' => 'application/vnd.intergeo', + 'icc' => 'application/vnd.iccprofile', + 'ice' => 'x-conference/x-cooltalk', + 'icm' => 'application/vnd.iccprofile', + 'ico' => 'image/x-icon', + 'ics' => 'text/calendar', + 'ief' => 'image/ief', + 'ifb' => 'text/calendar', + 'ifm' => 'application/vnd.shana.informed.formdata', + 'iges' => 'model/iges', + 'igl' => 'application/vnd.igloader', + 'igm' => 'application/vnd.insors.igm', + 'igs' => 'model/iges', + 'igx' => 'application/vnd.micrografx.igx', + 'iif' => 'application/vnd.shana.informed.interchange', + 'img' => 'application/octet-stream', + 'imp' => 'application/vnd.accpac.simply.imp', + 'ims' => 'application/vnd.ms-ims', + 'in' => 'text/plain', + 'ini' => 'text/plain', + 'ink' => 'application/inkml+xml', + 'inkml' => 'application/inkml+xml', + 'install' => 'application/x-install-instructions', + 'iota' => 'application/vnd.astraea-software.iota', + 'ipfix' => 'application/ipfix', + 'ipk' => 'application/vnd.shana.informed.package', + 'irm' => 'application/vnd.ibm.rights-management', + 'irp' => 'application/vnd.irepository.package+xml', + 'iso' => 'application/x-iso9660-image', + 'itp' => 'application/vnd.shana.informed.formtemplate', + 'its' => 'application/its+xml', + 'ivp' => 'application/vnd.immervision-ivp', + 'ivu' => 'application/vnd.immervision-ivu', + 'jad' => 'text/vnd.sun.j2me.app-descriptor', + 'jade' => 'text/jade', + 'jam' => 'application/vnd.jam', + 'jar' => 'application/java-archive', + 'jardiff' => 'application/x-java-archive-diff', + 'java' => 'text/x-java-source', + 'jhc' => 'image/jphc', + 'jisp' => 'application/vnd.jisp', + 'jls' => 'image/jls', + 'jlt' => 'application/vnd.hp-jlyt', + 'jng' => 'image/x-jng', + 'jnlp' => 'application/x-java-jnlp-file', + 'joda' => 'application/vnd.joost.joda-archive', + 'jp2' => 'image/jp2', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpf' => 'image/jpx', + 'jpg' => 'image/jpeg', + 'jpg2' => 'image/jp2', + 'jpgm' => 'video/jpm', + 'jpgv' => 'video/jpeg', + 'jph' => 'image/jph', + 'jpm' => 'video/jpm', + 'jpx' => 'image/jpx', + 'js' => 'application/javascript', + 'json' => 'application/json', + 'json5' => 'application/json5', + 'jsonld' => 'application/ld+json', + 'jsonml' => 'application/jsonml+json', + 'jsx' => 'text/jsx', + 'jxr' => 'image/jxr', + 'jxra' => 'image/jxra', + 'jxrs' => 'image/jxrs', + 'jxs' => 'image/jxs', + 'jxsc' => 'image/jxsc', + 'jxsi' => 'image/jxsi', + 'jxss' => 'image/jxss', + 'kar' => 'audio/midi', + 'karbon' => 'application/vnd.kde.karbon', + 'kdb' => 'application/octet-stream', + 'kdbx' => 'application/x-keepass2', + 'key' => 'application/vnd.apple.keynote', + 'kfo' => 'application/vnd.kde.kformula', + 'kia' => 'application/vnd.kidspiration', + 'kml' => 'application/vnd.google-earth.kml+xml', + 'kmz' => 'application/vnd.google-earth.kmz', + 'kne' => 'application/vnd.kinar', + 'knp' => 'application/vnd.kinar', + 'kon' => 'application/vnd.kde.kontour', + 'kpr' => 'application/vnd.kde.kpresenter', + 'kpt' => 'application/vnd.kde.kpresenter', + 'kpxx' => 'application/vnd.ds-keypoint', + 'ksp' => 'application/vnd.kde.kspread', + 'ktr' => 'application/vnd.kahootz', + 'ktx' => 'image/ktx', + 'ktx2' => 'image/ktx2', + 'ktz' => 'application/vnd.kahootz', + 'kwd' => 'application/vnd.kde.kword', + 'kwt' => 'application/vnd.kde.kword', + 'lasxml' => 'application/vnd.las.las+xml', + 'latex' => 'application/x-latex', + 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', + 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', + 'les' => 'application/vnd.hhe.lesson-player', + 'less' => 'text/less', + 'lgr' => 'application/lgr+xml', + 'lha' => 'application/octet-stream', + 'link66' => 'application/vnd.route66.link66+xml', + 'list' => 'text/plain', + 'list3820' => 'application/vnd.ibm.modcap', + 'listafp' => 'application/vnd.ibm.modcap', + 'litcoffee' => 'text/coffeescript', + 'lnk' => 'application/x-ms-shortcut', + 'log' => 'text/plain', + 'lostxml' => 'application/lost+xml', + 'lrf' => 'application/octet-stream', + 'lrm' => 'application/vnd.ms-lrm', + 'ltf' => 'application/vnd.frogans.ltf', + 'lua' => 'text/x-lua', + 'luac' => 'application/x-lua-bytecode', + 'lvp' => 'audio/vnd.lucent.voice', + 'lwp' => 'application/vnd.lotus-wordpro', + 'lzh' => 'application/octet-stream', + 'm1v' => 'video/mpeg', + 'm2a' => 'audio/mpeg', + 'm2v' => 'video/mpeg', + 'm3a' => 'audio/mpeg', + 'm3u' => 'text/plain', + 'm3u8' => 'application/vnd.apple.mpegurl', + 'm4a' => 'audio/x-m4a', + 'm4p' => 'application/mp4', + 'm4u' => 'application/vnd.mpegurl', + 'm4v' => 'video/x-m4v', + 'm13' => 'application/x-msmediaview', + 'm14' => 'application/x-msmediaview', + 'm21' => 'application/mp21', + 'ma' => 'application/mathematica', + 'mads' => 'application/mads+xml', + 'maei' => 'application/mmt-aei+xml', + 'mag' => 'application/vnd.ecowin.chart', + 'maker' => 'application/vnd.framemaker', + 'man' => 'text/troff', + 'manifest' => 'text/cache-manifest', + 'map' => 'application/json', + 'mar' => 'application/octet-stream', + 'markdown' => 'text/markdown', + 'mathml' => 'application/mathml+xml', + 'mb' => 'application/mathematica', + 'mbk' => 'application/vnd.mobius.mbk', + 'mbox' => 'application/mbox', + 'mc1' => 'application/vnd.medcalcdata', + 'mcd' => 'application/vnd.mcd', + 'mcurl' => 'text/vnd.curl.mcurl', + 'md' => 'text/markdown', + 'mdb' => 'application/x-msaccess', + 'mdi' => 'image/vnd.ms-modi', + 'mdx' => 'text/mdx', + 'me' => 'text/troff', + 'mesh' => 'model/mesh', + 'meta4' => 'application/metalink4+xml', + 'metalink' => 'application/metalink+xml', + 'mets' => 'application/mets+xml', + 'mfm' => 'application/vnd.mfmp', + 'mft' => 'application/rpki-manifest', + 'mgp' => 'application/vnd.osgeo.mapguide.package', + 'mgz' => 'application/vnd.proteus.magazine', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mie' => 'application/x-mie', + 'mif' => 'application/vnd.mif', + 'mime' => 'message/rfc822', + 'mj2' => 'video/mj2', + 'mjp2' => 'video/mj2', + 'mjs' => 'application/javascript', + 'mk3d' => 'video/x-matroska', + 'mka' => 'audio/x-matroska', + 'mkd' => 'text/x-markdown', + 'mks' => 'video/x-matroska', + 'mkv' => 'video/x-matroska', + 'mlp' => 'application/vnd.dolby.mlp', + 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', + 'mmf' => 'application/vnd.smaf', + 'mml' => 'text/mathml', + 'mmr' => 'image/vnd.fujixerox.edmics-mmr', + 'mng' => 'video/x-mng', + 'mny' => 'application/x-msmoney', + 'mobi' => 'application/x-mobipocket-ebook', + 'mods' => 'application/mods+xml', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'mp2' => 'audio/mpeg', + 'mp2a' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mp4a' => 'audio/mp4', + 'mp4s' => 'application/mp4', + 'mp4v' => 'video/mp4', + 'mp21' => 'application/mp21', + 'mpc' => 'application/vnd.mophun.certificate', + 'mpd' => 'application/dash+xml', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpg4' => 'video/mp4', + 'mpga' => 'audio/mpeg', + 'mpkg' => 'application/vnd.apple.installer+xml', + 'mpm' => 'application/vnd.blueice.multipass', + 'mpn' => 'application/vnd.mophun.application', + 'mpp' => 'application/vnd.ms-project', + 'mpt' => 'application/vnd.ms-project', + 'mpy' => 'application/vnd.ibm.minipay', + 'mqy' => 'application/vnd.mobius.mqy', + 'mrc' => 'application/marc', + 'mrcx' => 'application/marcxml+xml', + 'ms' => 'text/troff', + 'mscml' => 'application/mediaservercontrol+xml', + 'mseed' => 'application/vnd.fdsn.mseed', + 'mseq' => 'application/vnd.mseq', + 'msf' => 'application/vnd.epson.msf', + 'msg' => 'application/vnd.ms-outlook', + 'msh' => 'model/mesh', + 'msi' => 'application/x-msdownload', + 'msl' => 'application/vnd.mobius.msl', + 'msm' => 'application/octet-stream', + 'msp' => 'application/octet-stream', + 'msty' => 'application/vnd.muvee.style', + 'mtl' => 'model/mtl', + 'mts' => 'model/vnd.mts', + 'mus' => 'application/vnd.musician', + 'musd' => 'application/mmt-usd+xml', + 'musicxml' => 'application/vnd.recordare.musicxml+xml', + 'mvb' => 'application/x-msmediaview', + 'mwf' => 'application/vnd.mfer', + 'mxf' => 'application/mxf', + 'mxl' => 'application/vnd.recordare.musicxml', + 'mxmf' => 'audio/mobile-xmf', + 'mxml' => 'application/xv+xml', + 'mxs' => 'application/vnd.triscape.mxs', + 'mxu' => 'video/vnd.mpegurl', + 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', + 'n3' => 'text/n3', + 'nb' => 'application/mathematica', + 'nbp' => 'application/vnd.wolfram.player', + 'nc' => 'application/x-netcdf', + 'ncx' => 'application/x-dtbncx+xml', + 'nfo' => 'text/x-nfo', + 'ngdat' => 'application/vnd.nokia.n-gage.data', + 'nitf' => 'application/vnd.nitf', + 'nlu' => 'application/vnd.neurolanguage.nlu', + 'nml' => 'application/vnd.enliven', + 'nnd' => 'application/vnd.noblenet-directory', + 'nns' => 'application/vnd.noblenet-sealer', + 'nnw' => 'application/vnd.noblenet-web', + 'npx' => 'image/vnd.net-fpx', + 'nq' => 'application/n-quads', + 'nsc' => 'application/x-conference', + 'nsf' => 'application/vnd.lotus-notes', + 'nt' => 'application/n-triples', + 'ntf' => 'application/vnd.nitf', + 'numbers' => 'application/vnd.apple.numbers', + 'nzb' => 'application/x-nzb', + 'oa2' => 'application/vnd.fujitsu.oasys2', + 'oa3' => 'application/vnd.fujitsu.oasys3', + 'oas' => 'application/vnd.fujitsu.oasys', + 'obd' => 'application/x-msbinder', + 'obgx' => 'application/vnd.openblox.game+xml', + 'obj' => 'model/obj', + 'oda' => 'application/oda', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odft' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'oga' => 'audio/ogg', + 'ogex' => 'model/vnd.opengex', + 'ogg' => 'audio/ogg', + 'ogv' => 'video/ogg', + 'ogx' => 'application/ogg', + 'omdoc' => 'application/omdoc+xml', + 'onepkg' => 'application/onenote', + 'onetmp' => 'application/onenote', + 'onetoc' => 'application/onenote', + 'onetoc2' => 'application/onenote', + 'opf' => 'application/oebps-package+xml', + 'opml' => 'text/x-opml', + 'oprc' => 'application/vnd.palm', + 'opus' => 'audio/ogg', + 'org' => 'text/x-org', + 'osf' => 'application/vnd.yamaha.openscoreformat', + 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', + 'osm' => 'application/vnd.openstreetmap.data+xml', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'otf' => 'font/otf', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'ova' => 'application/x-virtualbox-ova', + 'ovf' => 'application/x-virtualbox-ovf', + 'owl' => 'application/rdf+xml', + 'oxps' => 'application/oxps', + 'oxt' => 'application/vnd.openofficeorg.extension', + 'p' => 'text/x-pascal', + 'p7a' => 'application/x-pkcs7-signature', + 'p7b' => 'application/x-pkcs7-certificates', + 'p7c' => 'application/pkcs7-mime', + 'p7m' => 'application/pkcs7-mime', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'p8' => 'application/pkcs8', + 'p10' => 'application/x-pkcs10', + 'p12' => 'application/x-pkcs12', + 'pac' => 'application/x-ns-proxy-autoconfig', + 'pages' => 'application/vnd.apple.pages', + 'pas' => 'text/x-pascal', + 'paw' => 'application/vnd.pawaafile', + 'pbd' => 'application/vnd.powerbuilder6', + 'pbm' => 'image/x-portable-bitmap', + 'pcap' => 'application/vnd.tcpdump.pcap', + 'pcf' => 'application/x-font-pcf', + 'pcl' => 'application/vnd.hp-pcl', + 'pclxl' => 'application/vnd.hp-pclxl', + 'pct' => 'image/x-pict', + 'pcurl' => 'application/vnd.curl.pcurl', + 'pcx' => 'image/x-pcx', + 'pdb' => 'application/x-pilot', + 'pde' => 'text/x-processing', + 'pdf' => 'application/pdf', + 'pem' => 'application/x-x509-user-cert', + 'pfa' => 'application/x-font-type1', + 'pfb' => 'application/x-font-type1', + 'pfm' => 'application/x-font-type1', + 'pfr' => 'application/font-tdpfr', + 'pfx' => 'application/x-pkcs12', + 'pgm' => 'image/x-portable-graymap', + 'pgn' => 'application/x-chess-pgn', + 'pgp' => 'application/pgp', + 'php' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'phtml' => 'application/x-httpd-php', + 'pic' => 'image/x-pict', + 'pkg' => 'application/octet-stream', + 'pki' => 'application/pkixcmp', + 'pkipath' => 'application/pkix-pkipath', + 'pkpass' => 'application/vnd.apple.pkpass', + 'pl' => 'application/x-perl', + 'plb' => 'application/vnd.3gpp.pic-bw-large', + 'plc' => 'application/vnd.mobius.plc', + 'plf' => 'application/vnd.pocketlearn', + 'pls' => 'application/pls+xml', + 'pm' => 'application/x-perl', + 'pml' => 'application/vnd.ctc-posml', + 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'portpkg' => 'application/vnd.macports.portpkg', + 'pot' => 'application/vnd.ms-powerpoint', + 'potm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppa' => 'application/vnd.ms-powerpoint', + 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', + 'ppd' => 'application/vnd.cups-ppd', + 'ppm' => 'image/x-portable-pixmap', + 'pps' => 'application/vnd.ms-powerpoint', + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'ppt' => 'application/powerpoint', + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'pqa' => 'application/vnd.palm', + 'prc' => 'application/x-pilot', + 'pre' => 'application/vnd.lotus-freelance', + 'prf' => 'application/pics-rules', + 'provx' => 'application/provenance+xml', + 'ps' => 'application/postscript', + 'psb' => 'application/vnd.3gpp.pic-bw-small', + 'psd' => 'application/x-photoshop', + 'psf' => 'application/x-font-linux-psf', + 'pskcxml' => 'application/pskc+xml', + 'pti' => 'image/prs.pti', + 'ptid' => 'application/vnd.pvi.ptid1', + 'pub' => 'application/x-mspublisher', + 'pvb' => 'application/vnd.3gpp.pic-bw-var', + 'pwn' => 'application/vnd.3m.post-it-notes', + 'pya' => 'audio/vnd.ms-playready.media.pya', + 'pyv' => 'video/vnd.ms-playready.media.pyv', + 'qam' => 'application/vnd.epson.quickanime', + 'qbo' => 'application/vnd.intu.qbo', + 'qfx' => 'application/vnd.intu.qfx', + 'qps' => 'application/vnd.publishare-delta-tree', + 'qt' => 'video/quicktime', + 'qwd' => 'application/vnd.quark.quarkxpress', + 'qwt' => 'application/vnd.quark.quarkxpress', + 'qxb' => 'application/vnd.quark.quarkxpress', + 'qxd' => 'application/vnd.quark.quarkxpress', + 'qxl' => 'application/vnd.quark.quarkxpress', + 'qxt' => 'application/vnd.quark.quarkxpress', + 'ra' => 'audio/x-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'raml' => 'application/raml+yaml', + 'rapd' => 'application/route-apd+xml', + 'rar' => 'application/x-rar', + 'ras' => 'image/x-cmu-raster', + 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', + 'rdf' => 'application/rdf+xml', + 'rdz' => 'application/vnd.data-vision.rdz', + 'relo' => 'application/p2p-overlay+xml', + 'rep' => 'application/vnd.businessobjects', + 'res' => 'application/x-dtbresource+xml', + 'rgb' => 'image/x-rgb', + 'rif' => 'application/reginfo+xml', + 'rip' => 'audio/vnd.rip', + 'ris' => 'application/x-research-info-systems', + 'rl' => 'application/resource-lists+xml', + 'rlc' => 'image/vnd.fujixerox.edmics-rlc', + 'rld' => 'application/resource-lists-diff+xml', + 'rm' => 'audio/x-pn-realaudio', + 'rmi' => 'audio/midi', + 'rmp' => 'audio/x-pn-realaudio-plugin', + 'rms' => 'application/vnd.jcp.javame.midlet-rms', + 'rmvb' => 'application/vnd.rn-realmedia-vbr', + 'rnc' => 'application/relax-ng-compact-syntax', + 'rng' => 'application/xml', + 'roa' => 'application/rpki-roa', + 'roff' => 'text/troff', + 'rp9' => 'application/vnd.cloanto.rp9', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'rpss' => 'application/vnd.nokia.radio-presets', + 'rpst' => 'application/vnd.nokia.radio-preset', + 'rq' => 'application/sparql-query', + 'rs' => 'application/rls-services+xml', + 'rsa' => 'application/x-pkcs7', + 'rsat' => 'application/atsc-rsat+xml', + 'rsd' => 'application/rsd+xml', + 'rsheet' => 'application/urc-ressheet+xml', + 'rss' => 'application/rss+xml', + 'rtf' => 'text/rtf', + 'rtx' => 'text/richtext', + 'run' => 'application/x-makeself', + 'rusd' => 'application/route-usd+xml', + 'rv' => 'video/vnd.rn-realvideo', + 's' => 'text/x-asm', + 's3m' => 'audio/s3m', + 'saf' => 'application/vnd.yamaha.smaf-audio', + 'sass' => 'text/x-sass', + 'sbml' => 'application/sbml+xml', + 'sc' => 'application/vnd.ibm.secure-container', + 'scd' => 'application/x-msschedule', + 'scm' => 'application/vnd.lotus-screencam', + 'scq' => 'application/scvp-cv-request', + 'scs' => 'application/scvp-cv-response', + 'scss' => 'text/x-scss', + 'scurl' => 'text/vnd.curl.scurl', + 'sda' => 'application/vnd.stardivision.draw', + 'sdc' => 'application/vnd.stardivision.calc', + 'sdd' => 'application/vnd.stardivision.impress', + 'sdkd' => 'application/vnd.solent.sdkm+xml', + 'sdkm' => 'application/vnd.solent.sdkm+xml', + 'sdp' => 'application/sdp', + 'sdw' => 'application/vnd.stardivision.writer', + 'sea' => 'application/octet-stream', + 'see' => 'application/vnd.seemail', + 'seed' => 'application/vnd.fdsn.seed', + 'sema' => 'application/vnd.sema', + 'semd' => 'application/vnd.semd', + 'semf' => 'application/vnd.semf', + 'senmlx' => 'application/senml+xml', + 'sensmlx' => 'application/sensml+xml', + 'ser' => 'application/java-serialized-object', + 'setpay' => 'application/set-payment-initiation', + 'setreg' => 'application/set-registration-initiation', + 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', + 'sfs' => 'application/vnd.spotfire.sfs', + 'sfv' => 'text/x-sfv', + 'sgi' => 'image/sgi', + 'sgl' => 'application/vnd.stardivision.writer-global', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', + 'shex' => 'text/shex', + 'shf' => 'application/shf+xml', + 'shtml' => 'text/html', + 'sid' => 'image/x-mrsid-image', + 'sieve' => 'application/sieve', + 'sig' => 'application/pgp-signature', + 'sil' => 'audio/silk', + 'silo' => 'model/mesh', + 'sis' => 'application/vnd.symbian.install', + 'sisx' => 'application/vnd.symbian.install', + 'sit' => 'application/x-stuffit', + 'sitx' => 'application/x-stuffitx', + 'siv' => 'application/sieve', + 'skd' => 'application/vnd.koan', + 'skm' => 'application/vnd.koan', + 'skp' => 'application/vnd.koan', + 'skt' => 'application/vnd.koan', + 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', + 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', + 'slim' => 'text/slim', + 'slm' => 'text/slim', + 'sls' => 'application/route-s-tsid+xml', + 'slt' => 'application/vnd.epson.salt', + 'sm' => 'application/vnd.stepmania.stepchart', + 'smf' => 'application/vnd.stardivision.math', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'smv' => 'video/x-smv', + 'smzip' => 'application/vnd.stepmania.package', + 'snd' => 'audio/basic', + 'snf' => 'application/x-font-snf', + 'so' => 'application/octet-stream', + 'spc' => 'application/x-pkcs7-certificates', + 'spdx' => 'text/spdx', + 'spf' => 'application/vnd.yamaha.smaf-phrase', + 'spl' => 'application/x-futuresplash', + 'spot' => 'text/vnd.in3d.spot', + 'spp' => 'application/scvp-vp-response', + 'spq' => 'application/scvp-vp-request', + 'spx' => 'audio/ogg', + 'sql' => 'application/x-sql', + 'src' => 'application/x-wais-source', + 'srt' => 'application/x-subrip', + 'sru' => 'application/sru+xml', + 'srx' => 'application/sparql-results+xml', + 'ssdl' => 'application/ssdl+xml', + 'sse' => 'application/vnd.kodak-descriptor', + 'ssf' => 'application/vnd.epson.ssf', + 'ssml' => 'application/ssml+xml', + 'sst' => 'application/octet-stream', + 'st' => 'application/vnd.sailingtracker.track', + 'stc' => 'application/vnd.sun.xml.calc.template', + 'std' => 'application/vnd.sun.xml.draw.template', + 'stf' => 'application/vnd.wt.stf', + 'sti' => 'application/vnd.sun.xml.impress.template', + 'stk' => 'application/hyperstudio', + 'stl' => 'model/stl', + 'str' => 'application/vnd.pg.format', + 'stw' => 'application/vnd.sun.xml.writer.template', + 'styl' => 'text/stylus', + 'stylus' => 'text/stylus', + 'sub' => 'text/vnd.dvb.subtitle', + 'sus' => 'application/vnd.sus-calendar', + 'susp' => 'application/vnd.sus-calendar', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'svc' => 'application/vnd.dvb.service', + 'svd' => 'application/vnd.svd', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + 'swa' => 'application/x-director', + 'swf' => 'application/x-shockwave-flash', + 'swi' => 'application/vnd.aristanetworks.swi', + 'swidtag' => 'application/swid+xml', + 'sxc' => 'application/vnd.sun.xml.calc', + 'sxd' => 'application/vnd.sun.xml.draw', + 'sxg' => 'application/vnd.sun.xml.writer.global', + 'sxi' => 'application/vnd.sun.xml.impress', + 'sxm' => 'application/vnd.sun.xml.math', + 'sxw' => 'application/vnd.sun.xml.writer', + 't' => 'text/troff', + 't3' => 'application/x-t3vm-image', + 't38' => 'image/t38', + 'taglet' => 'application/vnd.mynfc', + 'tao' => 'application/vnd.tao.intent-module-archive', + 'tap' => 'image/vnd.tencent.tap', + 'tar' => 'application/x-tar', + 'tcap' => 'application/vnd.3gpp2.tcap', + 'tcl' => 'application/x-tcl', + 'td' => 'application/urc-targetdesc+xml', + 'teacher' => 'application/vnd.smart.teacher', + 'tei' => 'application/tei+xml', + 'teicorpus' => 'application/tei+xml', + 'tex' => 'application/x-tex', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'text' => 'text/plain', + 'tfi' => 'application/thraud+xml', + 'tfm' => 'application/x-tex-tfm', + 'tfx' => 'image/tiff-fx', + 'tga' => 'image/x-tga', + 'tgz' => 'application/x-tar', + 'thmx' => 'application/vnd.ms-officetheme', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tk' => 'application/x-tcl', + 'tmo' => 'application/vnd.tmobile-livetv', + 'toml' => 'application/toml', + 'torrent' => 'application/x-bittorrent', + 'tpl' => 'application/vnd.groove-tool-template', + 'tpt' => 'application/vnd.trid.tpt', + 'tr' => 'text/troff', + 'tra' => 'application/vnd.trueapp', + 'trm' => 'application/x-msterminal', + 'ts' => 'video/mp2t', + 'tsd' => 'application/timestamped-data', + 'tsv' => 'text/tab-separated-values', + 'ttc' => 'font/collection', + 'ttf' => 'font/ttf', + 'ttl' => 'text/turtle', + 'ttml' => 'application/ttml+xml', + 'twd' => 'application/vnd.simtech-mindmapper', + 'twds' => 'application/vnd.simtech-mindmapper', + 'txd' => 'application/vnd.genomatix.tuxedo', + 'txf' => 'application/vnd.mobius.txf', + 'txt' => 'text/plain', + 'u8dsn' => 'message/global-delivery-status', + 'u8hdr' => 'message/global-headers', + 'u8mdn' => 'message/global-disposition-notification', + 'u8msg' => 'message/global', + 'u32' => 'application/x-authorware-bin', + 'ubj' => 'application/ubjson', + 'udeb' => 'application/x-debian-package', + 'ufd' => 'application/vnd.ufdl', + 'ufdl' => 'application/vnd.ufdl', + 'ulx' => 'application/x-glulx', + 'umj' => 'application/vnd.umajin', + 'unityweb' => 'application/vnd.unity', + 'uoml' => 'application/vnd.uoml+xml', + 'uri' => 'text/uri-list', + 'uris' => 'text/uri-list', + 'urls' => 'text/uri-list', + 'usdz' => 'model/vnd.usdz+zip', + 'ustar' => 'application/x-ustar', + 'utz' => 'application/vnd.uiq.theme', + 'uu' => 'text/x-uuencode', + 'uva' => 'audio/vnd.dece.audio', + 'uvd' => 'application/vnd.dece.data', + 'uvf' => 'application/vnd.dece.data', + 'uvg' => 'image/vnd.dece.graphic', + 'uvh' => 'video/vnd.dece.hd', + 'uvi' => 'image/vnd.dece.graphic', + 'uvm' => 'video/vnd.dece.mobile', + 'uvp' => 'video/vnd.dece.pd', + 'uvs' => 'video/vnd.dece.sd', + 'uvt' => 'application/vnd.dece.ttml+xml', + 'uvu' => 'video/vnd.uvvu.mp4', + 'uvv' => 'video/vnd.dece.video', + 'uvva' => 'audio/vnd.dece.audio', + 'uvvd' => 'application/vnd.dece.data', + 'uvvf' => 'application/vnd.dece.data', + 'uvvg' => 'image/vnd.dece.graphic', + 'uvvh' => 'video/vnd.dece.hd', + 'uvvi' => 'image/vnd.dece.graphic', + 'uvvm' => 'video/vnd.dece.mobile', + 'uvvp' => 'video/vnd.dece.pd', + 'uvvs' => 'video/vnd.dece.sd', + 'uvvt' => 'application/vnd.dece.ttml+xml', + 'uvvu' => 'video/vnd.uvvu.mp4', + 'uvvv' => 'video/vnd.dece.video', + 'uvvx' => 'application/vnd.dece.unspecified', + 'uvvz' => 'application/vnd.dece.zip', + 'uvx' => 'application/vnd.dece.unspecified', + 'uvz' => 'application/vnd.dece.zip', + 'vbox' => 'application/x-virtualbox-vbox', + 'vbox-extpack' => 'application/x-virtualbox-vbox-extpack', + 'vcard' => 'text/vcard', + 'vcd' => 'application/x-cdlink', + 'vcf' => 'text/x-vcard', + 'vcg' => 'application/vnd.groove-vcard', + 'vcs' => 'text/x-vcalendar', + 'vcx' => 'application/vnd.vcx', + 'vdi' => 'application/x-virtualbox-vdi', + 'vhd' => 'application/x-virtualbox-vhd', + 'vis' => 'application/vnd.visionary', + 'viv' => 'video/vnd.vivo', + 'vlc' => 'application/videolan', + 'vmdk' => 'application/x-virtualbox-vmdk', + 'vob' => 'video/x-ms-vob', + 'vor' => 'application/vnd.stardivision.writer', + 'vox' => 'application/x-authorware-bin', + 'vrml' => 'model/vrml', + 'vsd' => 'application/vnd.visio', + 'vsf' => 'application/vnd.vsf', + 'vss' => 'application/vnd.visio', + 'vst' => 'application/vnd.visio', + 'vsw' => 'application/vnd.visio', + 'vtf' => 'image/vnd.valve.source.texture', + 'vtt' => 'text/vtt', + 'vtu' => 'model/vnd.vtu', + 'vxml' => 'application/voicexml+xml', + 'w3d' => 'application/x-director', + 'wad' => 'application/x-doom', + 'wadl' => 'application/vnd.sun.wadl+xml', + 'war' => 'application/java-archive', + 'wasm' => 'application/wasm', + 'wav' => 'audio/x-wav', + 'wax' => 'audio/x-ms-wax', + 'wbmp' => 'image/vnd.wap.wbmp', + 'wbs' => 'application/vnd.criticaltools.wbs+xml', + 'wbxml' => 'application/wbxml', + 'wcm' => 'application/vnd.ms-works', + 'wdb' => 'application/vnd.ms-works', + 'wdp' => 'image/vnd.ms-photo', + 'weba' => 'audio/webm', + 'webapp' => 'application/x-web-app-manifest+json', + 'webm' => 'video/webm', + 'webmanifest' => 'application/manifest+json', + 'webp' => 'image/webp', + 'wg' => 'application/vnd.pmi.widget', + 'wgt' => 'application/widget', + 'wks' => 'application/vnd.ms-works', + 'wm' => 'video/x-ms-wm', + 'wma' => 'audio/x-ms-wma', + 'wmd' => 'application/x-ms-wmd', + 'wmf' => 'image/wmf', + 'wml' => 'text/vnd.wap.wml', + 'wmlc' => 'application/wmlc', + 'wmls' => 'text/vnd.wap.wmlscript', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'wmv' => 'video/x-ms-wmv', + 'wmx' => 'video/x-ms-wmx', + 'wmz' => 'application/x-msmetafile', + 'woff' => 'font/woff', + 'woff2' => 'font/woff2', + 'word' => 'application/msword', + 'wpd' => 'application/vnd.wordperfect', + 'wpl' => 'application/vnd.ms-wpl', + 'wps' => 'application/vnd.ms-works', + 'wqd' => 'application/vnd.wqd', + 'wri' => 'application/x-mswrite', + 'wrl' => 'model/vrml', + 'wsc' => 'message/vnd.wfa.wsc', + 'wsdl' => 'application/wsdl+xml', + 'wspolicy' => 'application/wspolicy+xml', + 'wtb' => 'application/vnd.webturbo', + 'wvx' => 'video/x-ms-wvx', + 'x3d' => 'model/x3d+xml', + 'x3db' => 'model/x3d+fastinfoset', + 'x3dbz' => 'model/x3d+binary', + 'x3dv' => 'model/x3d-vrml', + 'x3dvz' => 'model/x3d+vrml', + 'x3dz' => 'model/x3d+xml', + 'x32' => 'application/x-authorware-bin', + 'x_b' => 'model/vnd.parasolid.transmit.binary', + 'x_t' => 'model/vnd.parasolid.transmit.text', + 'xaml' => 'application/xaml+xml', + 'xap' => 'application/x-silverlight-app', + 'xar' => 'application/vnd.xara', + 'xav' => 'application/xcap-att+xml', + 'xbap' => 'application/x-ms-xbap', + 'xbd' => 'application/vnd.fujixerox.docuworks.binder', + 'xbm' => 'image/x-xbitmap', + 'xca' => 'application/xcap-caps+xml', + 'xcs' => 'application/calendar+xml', + 'xdf' => 'application/xcap-diff+xml', + 'xdm' => 'application/vnd.syncml.dm+xml', + 'xdp' => 'application/vnd.adobe.xdp+xml', + 'xdssc' => 'application/dssc+xml', + 'xdw' => 'application/vnd.fujixerox.docuworks', + 'xel' => 'application/xcap-el+xml', + 'xenc' => 'application/xenc+xml', + 'xer' => 'application/xcap-error+xml', + 'xfdf' => 'application/vnd.adobe.xfdf', + 'xfdl' => 'application/vnd.xfdl', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'xhvml' => 'application/xv+xml', + 'xif' => 'image/vnd.xiff', + 'xl' => 'application/excel', + 'xla' => 'application/vnd.ms-excel', + 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', + 'xlc' => 'application/vnd.ms-excel', + 'xlf' => 'application/xliff+xml', + 'xlm' => 'application/vnd.ms-excel', + 'xls' => 'application/vnd.ms-excel', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', + 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xlt' => 'application/vnd.ms-excel', + 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'xlw' => 'application/vnd.ms-excel', + 'xm' => 'audio/xm', + 'xml' => 'application/xml', + 'xns' => 'application/xcap-ns+xml', + 'xo' => 'application/vnd.olpc-sugar', + 'xop' => 'application/xop+xml', + 'xpi' => 'application/x-xpinstall', + 'xpl' => 'application/xproc+xml', + 'xpm' => 'image/x-xpixmap', + 'xpr' => 'application/vnd.is-xpr', + 'xps' => 'application/vnd.ms-xpsdocument', + 'xpw' => 'application/vnd.intercon.formnet', + 'xpx' => 'application/vnd.intercon.formnet', + 'xsd' => 'application/xml', + 'xsl' => 'application/xml', + 'xslt' => 'application/xslt+xml', + 'xsm' => 'application/vnd.syncml+xml', + 'xspf' => 'application/xspf+xml', + 'xul' => 'application/vnd.mozilla.xul+xml', + 'xvm' => 'application/xv+xml', + 'xvml' => 'application/xv+xml', + 'xwd' => 'image/x-xwindowdump', + 'xyz' => 'chemical/x-xyz', + 'xz' => 'application/x-xz', + 'yaml' => 'text/yaml', + 'yang' => 'application/yang', + 'yin' => 'application/yin+xml', + 'yml' => 'text/yaml', + 'ymp' => 'text/x-suse-ymp', + 'z' => 'application/x-compress', + 'z1' => 'application/x-zmachine', + 'z2' => 'application/x-zmachine', + 'z3' => 'application/x-zmachine', + 'z4' => 'application/x-zmachine', + 'z5' => 'application/x-zmachine', + 'z6' => 'application/x-zmachine', + 'z7' => 'application/x-zmachine', + 'z8' => 'application/x-zmachine', + 'zaz' => 'application/vnd.zzazz.deck+xml', + 'zip' => 'application/x-zip', + 'zir' => 'application/vnd.zul', + 'zirz' => 'application/vnd.zul', + 'zmm' => 'application/vnd.handheld-entertainment+xml', + 'zsh' => 'text/x-scriptzsh', + ]; + + public function lookupMimeType(string $extension): ?string + { + return self::MIME_TYPES_FOR_EXTENSIONS[$extension] ?? null; + } +} diff --git a/vendor/league/mime-type-detection/src/MimeTypeDetector.php b/vendor/league/mime-type-detection/src/MimeTypeDetector.php new file mode 100644 index 000000000..5d799d2a8 --- /dev/null +++ b/vendor/league/mime-type-detection/src/MimeTypeDetector.php @@ -0,0 +1,19 @@ +registerErrorHandler($errorLevelMap); diff --git a/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php index 237b71f61..8846e0a08 100644 --- a/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php +++ b/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php @@ -77,6 +77,7 @@ class DynamoDbHandler extends AbstractProcessingHandler if ($this->version === 3) { $formatted = $this->marshaler->marshalItem($filtered); } else { + /** @phpstan-ignore-next-line */ $formatted = $this->client->formatAttributes($filtered); } diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php index c30b1843c..2a171bd82 100644 --- a/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php +++ b/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php @@ -72,7 +72,7 @@ class FirePHPHandler extends AbstractProcessingHandler * * @see createHeader() * @param array $record - * @return string + * @return array */ protected function createRecordHeader(array $record) { diff --git a/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php index 71e466934..b6cde7c65 100644 --- a/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php +++ b/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php @@ -27,7 +27,7 @@ use Monolog\Formatter\GelfMessageFormatter; class GelfHandler extends AbstractProcessingHandler { /** - * @var Publisher the publisher object that sends the message to the server + * @var Publisher|PublisherInterface|IMessagePublisher the publisher object that sends the message to the server */ protected $publisher; diff --git a/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php index 179d62686..30258e36e 100644 --- a/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php +++ b/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php @@ -270,10 +270,10 @@ class HipChatHandler extends SocketHandler * will be the highest level from the given records. Datetime will be taken * from the first record. * - * @param $records + * @param array $records * @return array */ - private function combineRecords($records) + private function combineRecords(array $records) { $batchRecord = null; $batchRecords = array(); diff --git a/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php index 9d24dfe86..b0298fa6c 100644 --- a/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php +++ b/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php @@ -50,7 +50,7 @@ class RavenHandler extends AbstractProcessingHandler protected $ravenClient; /** - * @var LineFormatter The formatter to use for the logs generated via handleBatch() + * @var FormatterInterface The formatter to use for the logs generated via handleBatch() */ protected $batchFormatter; diff --git a/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php index bb00db509..3725db242 100644 --- a/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php +++ b/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php @@ -36,7 +36,7 @@ class RedisHandler extends AbstractProcessingHandler * @param string $key The key name to push records to * @param int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not - * @param int $capSize Number of entries to limit list size to + * @param int|false $capSize Number of entries to limit list size to */ public function __construct($redis, $key, $level = Logger::DEBUG, $bubble = true, $capSize = false) { diff --git a/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php index b52607d2e..ad6960cb2 100644 --- a/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php +++ b/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php @@ -154,7 +154,7 @@ class StreamHandler extends AbstractProcessingHandler return dirname(substr($stream, 7)); } - return; + return null; } private function createDir() diff --git a/vendor/monolog/monolog/src/Monolog/Logger.php b/vendor/monolog/monolog/src/Monolog/Logger.php index e649af51b..b8b4f55b4 100644 --- a/vendor/monolog/monolog/src/Monolog/Logger.php +++ b/vendor/monolog/monolog/src/Monolog/Logger.php @@ -522,7 +522,7 @@ class Logger implements LoggerInterface, ResettableInterface /** * Converts PSR-3 levels to Monolog ones if necessary * - * @param string|int Level number (monolog) or name (PSR-3) + * @param string|int $level Level number (monolog) or name (PSR-3) * @return int */ public static function toMonologLevel($level) diff --git a/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php index 008850545..a318af7e4 100644 --- a/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php +++ b/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php @@ -22,6 +22,24 @@ use Monolog\Utils; */ class PsrLogMessageProcessor implements ProcessorInterface { + const SIMPLE_DATE = "Y-m-d\TH:i:s.uP"; + + /** @var string|null */ + private $dateFormat; + + /** @var bool */ + private $removeUsedContextFields; + + /** + * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format + * @param bool $removeUsedContextFields If set to true the fields interpolated into message gets unset + */ + public function __construct($dateFormat = null, $removeUsedContextFields = false) + { + $this->dateFormat = $dateFormat; + $this->removeUsedContextFields = $removeUsedContextFields; + } + /** * @param array $record * @return array @@ -34,12 +52,25 @@ class PsrLogMessageProcessor implements ProcessorInterface $replacements = array(); foreach ($record['context'] as $key => $val) { + $placeholder = '{' . $key . '}'; + if (strpos($record['message'], $placeholder) === false) { + continue; + } + if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, "__toString"))) { - $replacements['{'.$key.'}'] = $val; + $replacements[$placeholder] = $val; + } elseif ($val instanceof \DateTime) { + $replacements[$placeholder] = $val->format($this->dateFormat ?: static::SIMPLE_DATE); } elseif (is_object($val)) { - $replacements['{'.$key.'}'] = '[object '.Utils::getClass($val).']'; + $replacements[$placeholder] = '[object '.Utils::getClass($val).']'; + } elseif (is_array($val)) { + $replacements[$placeholder] = 'array'.Utils::jsonEncode($val, null, true); } else { - $replacements['{'.$key.'}'] = '['.gettype($val).']'; + $replacements[$placeholder] = '['.gettype($val).']'; + } + + if ($this->removeUsedContextFields) { + unset($record['context'][$key]); } } diff --git a/vendor/monolog/monolog/src/Monolog/Utils.php b/vendor/monolog/monolog/src/Monolog/Utils.php index 712b19692..7f1ba129e 100644 --- a/vendor/monolog/monolog/src/Monolog/Utils.php +++ b/vendor/monolog/monolog/src/Monolog/Utils.php @@ -168,7 +168,7 @@ class Utils * Function converts the input in place in the passed variable so that it * can be used as a callback for array_walk_recursive. * - * @param mixed &$data Input to check and convert if needed + * @param mixed $data Input to check and convert if needed, passed by ref * @private */ public static function detectAndCleanUtf8(&$data) diff --git a/vendor/nikic/php-parser/README.md b/vendor/nikic/php-parser/README.md index f1dd929d7..4c8deada9 100644 --- a/vendor/nikic/php-parser/README.md +++ b/vendor/nikic/php-parser/README.md @@ -1,12 +1,12 @@ PHP Parser ========== -[![Build Status](https://travis-ci.org/nikic/PHP-Parser.svg?branch=master)](https://travis-ci.org/nikic/PHP-Parser) [![Coverage Status](https://coveralls.io/repos/github/nikic/PHP-Parser/badge.svg?branch=master)](https://coveralls.io/github/nikic/PHP-Parser?branch=master) +[![Coverage Status](https://coveralls.io/repos/github/nikic/PHP-Parser/badge.svg?branch=master)](https://coveralls.io/github/nikic/PHP-Parser?branch=master) -This is a PHP 5.2 to PHP 7.4 parser written in PHP. Its purpose is to simplify static code analysis and +This is a PHP 5.2 to PHP 8.0 parser written in PHP. Its purpose is to simplify static code analysis and manipulation. -[**Documentation for version 4.x**][doc_master] (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 7.4). +[**Documentation for version 4.x**][doc_master] (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 8.0). [Documentation for version 3.x][doc_3_x] (unsupported; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2). @@ -15,7 +15,7 @@ Features The main features provided by this library are: - * Parsing PHP 5 and PHP 7 code into an abstract syntax tree (AST). + * Parsing PHP 5, PHP 7, and PHP 8 code into an abstract syntax tree (AST). * Invalid code can be parsed into a partial AST. * The AST contains accurate location information. * Dumping the AST in human-readable form. diff --git a/vendor/nikic/php-parser/grammar/php7.y b/vendor/nikic/php-parser/grammar/php7.y index 8add78338..4ca244d8a 100644 --- a/vendor/nikic/php-parser/grammar/php7.y +++ b/vendor/nikic/php-parser/grammar/php7.y @@ -348,10 +348,7 @@ function_declaration_statement: ; class_declaration_statement: - class_entry_type identifier extends_from implements_list '{' class_statement_list '}' - { $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6, 'attrGroups' => []]]; - $this->checkClass($$, #2); } - | attributes class_entry_type identifier extends_from implements_list '{' class_statement_list '}' + optional_attributes class_entry_type identifier extends_from implements_list '{' class_statement_list '}' { $$ = Stmt\Class_[$3, ['type' => $2, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]]; $this->checkClass($$, #3); } | optional_attributes T_INTERFACE identifier interface_extends_list '{' class_statement_list '}' @@ -601,7 +598,7 @@ non_empty_global_var_list: ; global_var: - simple_variable { $$ = Expr\Variable[$1]; } + simple_variable { $$ = $1; } ; static_var_list: @@ -1007,7 +1004,7 @@ callable_expr: ; callable_variable: - simple_variable { $$ = Expr\Variable[$1]; } + simple_variable { $$ = $1; } | array_object_dereferencable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | array_object_dereferencable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } | function_call { $$ = $1; } @@ -1032,15 +1029,15 @@ variable: ; simple_variable: - T_VARIABLE { $$ = parseVar($1); } - | '$' '{' expr '}' { $$ = $3; } + plain_variable { $$ = $1; } + | '$' '{' expr '}' { $$ = Expr\Variable[$3]; } | '$' simple_variable { $$ = Expr\Variable[$2]; } - | '$' error { $$ = Expr\Error[]; $this->errorState = 2; } + | '$' error { $$ = Expr\Variable[Expr\Error[]]; $this->errorState = 2; } ; static_member_prop_name: simple_variable - { $var = $1; $$ = \is_string($var) ? Node\VarLikeIdentifier[$var] : $var; } + { $var = $1->name; $$ = \is_string($var) ? Node\VarLikeIdentifier[$var] : $var; } ; static_member: @@ -1049,7 +1046,7 @@ static_member: ; new_variable: - simple_variable { $$ = Expr\Variable[$1]; } + simple_variable { $$ = $1; } | new_variable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | new_variable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } | new_variable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; } @@ -1063,13 +1060,13 @@ new_variable: member_name: identifier_ex { $$ = $1; } | '{' expr '}' { $$ = $2; } - | simple_variable { $$ = Expr\Variable[$1]; } + | simple_variable { $$ = $1; } ; property_name: identifier { $$ = $1; } | '{' expr '}' { $$ = $2; } - | simple_variable { $$ = Expr\Variable[$1]; } + | simple_variable { $$ = $1; } | error { $$ = Expr\Error[]; $this->errorState = 2; } ; diff --git a/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php b/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php index 39308ae62..84c0175ec 100644 --- a/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php +++ b/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php @@ -46,7 +46,8 @@ class TokenStream * @return bool */ public function haveBraces(int $startPos, int $endPos) : bool { - return $this->haveTokenImmediatelyBefore($startPos, '{') + return ($this->haveTokenImmediatelyBefore($startPos, '{') + || $this->haveTokenImmediatelyBefore($startPos, T_CURLY_OPEN)) && $this->haveTokenImmediatelyAfter($endPos, '}'); } @@ -201,6 +202,7 @@ class TokenStream public function haveBracesInRange(int $startPos, int $endPos) { return $this->haveTokenInRange($startPos, $endPos, '{') + || $this->haveTokenInRange($startPos, $endPos, T_CURLY_OPEN) || $this->haveTokenInRange($startPos, $endPos, '}'); } diff --git a/vendor/nikic/php-parser/lib/PhpParser/Lexer.php b/vendor/nikic/php-parser/lib/PhpParser/Lexer.php index b0c21ead2..832a3f4b8 100644 --- a/vendor/nikic/php-parser/lib/PhpParser/Lexer.php +++ b/vendor/nikic/php-parser/lib/PhpParser/Lexer.php @@ -85,7 +85,6 @@ class Lexer $scream = ini_set('xdebug.scream', '0'); - error_clear_last(); $this->tokens = @token_get_all($code); $this->postprocessTokens($errorHandler); diff --git a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php index cbfbd34aa..55d16585b 100644 --- a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php +++ b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php @@ -19,7 +19,7 @@ class Php7 extends \PhpParser\ParserAbstract { protected $tokenToSymbolMapSize = 392; protected $actionTableSize = 1162; - protected $gotoTableSize = 611; + protected $gotoTableSize = 588; protected $invalidSymbol = 165; protected $errorSymbol = 1; @@ -27,7 +27,7 @@ class Php7 extends \PhpParser\ParserAbstract protected $unexpectedTokenRule = 32767; protected $YY2TBLSTATE = 397; - protected $numNonLeafStates = 694; + protected $numNonLeafStates = 688; protected $symbolToName = array( "EOF", @@ -241,249 +241,249 @@ class Php7 extends \PhpParser\ParserAbstract ); protected $action = array( - 130, 131, 132, 555, 133, 134,-32766, 704, 705, 706, - 135, 36, -543, -552, 455,-32766, -543,-32766,-32766,-32766, - -552, 1152, 778, 927, -549, 969, 970, 0,-32766,-32766, - -32766, -549,-32766, 1219,-32766, 245,-32766, 962,-32766,-32766, - -32766,-32766,-32766, 461,-32766,-32766,-32766,-32766,-32766,-32766, - -32766,-32766, 124, -331, 707, -331,-32766, 388, 1031, 1032, - 1033, 1030, 1029, 1028,-32766, 435, 430, 2, 261, 136, - 371, 711, 712, 713, 714, 391, 789, 397, 1031, 1032, - 1033, 1030, 1029, 1028, 715, 716, 717, 718, 719, 720, - 721, 722, 723, 724, 725, 745, 556, 746, 747, 748, - 749, 737, 738, 372, 373, 740, 741, 726, 727, 728, - 730, 731, 732, 332, 771, 772, 773, 774, 775, 733, - 734, 557, 558, 766, 757, 755, 756, 752, 753, -294, - -189, 559, 560, 751, 561, 562, 563, 564, 565, 566, - 1235, 456, 783, -503, 889, 754, 567, 568, 928, 137, - -32766,-32766,-32766, 130, 131, 132, 555, 133, 134, 983, - 704, 705, 706, 135, 36,-32766,-32766,-32766,-32766, -552, - -32766,-32766,-32766, -552, 1152, 547, 101, 102, 103, 583, - -549,-32766,-32766,-32766, -549,-32766,-32766,-32766, 245,-32766, - 80,-32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766, - 959, 958, 957,-32766,-32766, -503, -503, 707, 1264,-32766, - 388, 1265,-32766,-32766,-32766, 235, 784,-32766, 778, 19, - -503, 261, 136, 371, 711, 712, 713, 714,-32766,-32766, - 397, 788, -503,-32766, -509,-32766,-32766, 715, 716, 717, - 718, 719, 720, 721, 722, 723, 724, 725, 745, 556, - 746, 747, 748, 749, 737, 738, 372, 373, 740, 741, - 726, 727, 728, 730, 731, 732, 332, 771, 772, 773, - 774, 775, 733, 734, 557, 558, 766, 757, 755, 756, - 752, 753, -294, -189, 559, 560, 751, 561, 562, 563, - 564, 565, 566, 309, 81, 82, 83, 139, 754, 567, - 568, 681, 137, 729, 699, 700, 701, 702, 703, 1239, - 704, 705, 706, 742, 743, 33, 1238, 84, 85, 86, + 130, 131, 132, 552, 133, 134, 0, 698, 699, 700, + 135, 36, 883, 528, 529,-32766, 1212,-32766,-32766,-32766, + -551, 1145, 772, 889, 430, 431, 1232, -551,-32766,-32766, + -32766, -293,-32766, 1231,-32766, 245,-32766, -189,-32766,-32766, + -32766,-32766,-32766, 458,-32766,-32766,-32766,-32766,-32766,-32766, + -32766,-32766, 124, 783, 701, 777,-32766, 388, 1024, 1025, + 1026, 1023, 1022, 1021,-32766, 428, 429, 955, 261, 136, + 372, 705, 706, 707, 708, 391, -188, 397, 1024, 1025, + 1026, 1023, 1022, 1021, 709, 710, 711, 712, 713, 714, + 715, 716, 717, 718, 719, 739, 553, 740, 741, 742, + 743, 731, 732, 373, 374, 734, 735, 720, 721, 722, + 724, 725, 726, 333, 765, 766, 767, 768, 769, 727, + 728, 554, 555, 760, 751, 749, 750, 746, 747, 778, + 2, 556, 557, 745, 558, 559, 560, 561, 562, 563, + -542, -548, 19, -502, -542, 748, 564, 565, -548, 137, + -32766,-32766,-32766, 130, 131, 132, 552, 133, 134, 976, + 698, 699, 700, 135, 36,-32766,-32766,-32766,-32766, 675, + -32766,-32766,-32766, 80, 1145, 544, -551,-32766,-32766, 309, + -551,-32766,-32766,-32766, -293,-32766,-32766,-32766, 245,-32766, + -189,-32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766, + 31, 433, 429,-32766,-32766, -502, -502, 701, 782,-32766, + 388, 391,-32766,-32766,-32766, 235, 126,-32766, -82, 142, + -502, 261, 136, 372, 705, 706, 707, 708, 247, -188, + 397, 292, -502,-32766, -508,-32766,-32766, 709, 710, 711, + 712, 713, 714, 715, 716, 717, 718, 719, 739, 553, + 740, 741, 742, 743, 731, 732, 373, 374, 734, 735, + 720, 721, 722, 724, 725, 726, 333, 765, 766, 767, + 768, 769, 727, 728, 554, 555, 760, 751, 749, 750, + 746, 747, 294, -82, 556, 557, 745, 558, 559, 560, + 561, 562, 563, 310, 81, 82, 83, -548, 748, 564, + 565, -548, 137, 723, 693, 694, 695, 696, 697,-32766, + 698, 699, 700, 736, 737, 33, 307, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 31, 263,-32766,-32766,-32766, 104, 105, 106, 577, 263, - 1216, 126, -188, 107, 142, 440, 441, 707,-32766,-32766, - -32766, 107, -254,-32766, 247,-32766,-32766,-32766,-32766,-32766, - -32766, 708, 709, 710, 711, 712, 713, 714, 293,-32766, - 776,-32766,-32766,-32766,-32766,-32766, 295, 715, 716, 717, - 718, 719, 720, 721, 722, 723, 724, 725, 745, 768, - 746, 747, 748, 749, 737, 738, 739, 767, 740, 741, - 726, 727, 728, 730, 731, 732, 770, 771, 772, 773, - 774, 775, 733, 734, 735, 736, 766, 757, 755, 756, - 752, 753, 529, 311, 744, 750, 751, 758, 759, 761, - 760, 762, 763, 234,-32766,-32766,-32766, 307, 754, 765, - 764, 48, 49, 50, 486, 51, 52, 481, 397, 18, - 321, 53, 54, 345, 55,-32766, 982,-32766,-32766,-32766, - -32766,-32766,-32766,-32767,-32767,-32767,-32767,-32767, 349,-32767, - -32767,-32767,-32767, 99, 100, 101, 102, 103, 814, 354, - 815, 1191, 356, 1152, 871, 271, 408, 871, 56, 57, - 409, 814, 410, 815, 58, -188, 59, 240, 241, 60, - 61, 62, 63, 64, 65, 66, 67,-32766, 26, 262, - 68, 412, 487, 411, 672, 967, 1185, 1186, 488, 1150, - 1216, 1154, 1153, 1155, 1183, 40, 23, 489, 1009, 490, - -82, 491, 147, 492, 969, 970, 493, 494, 786, 429, - 430, 42, 43, 413, 418, 415, 871, 44, 495, 391, - 496, 497, 248, 344, 320, 1159, 1154, 1153, 1155, 793, - 896, 498, 499, 500, 148, 1008, 861, 692, 787, 861, - 967, 1254, 501, 502, 150, 1173, 1174, 1175, 1176, 1170, - 1171, 281, 624, 24, 26, -14, 151, 1177, 1172, 969, - 970, 1154, 1153, 1155, 282, -82, 1216, -502, 152, 69, - 1183, 305, 306, 311, 34, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 154, -149, - -149, -149, 639, 640, 146, 376, 1159, 1159, 861, 615, - 616, 32, 243, 35, -149, 1216, -149, 121, -149, 873, - -149, 667, 873, 122, 667, 242, 1067, 1069, 501, 502, - 414, 1173, 1174, 1175, 1176, 1170, 1171, -501, 127, -502, - -502, 496, 497, 1177, 1172, -504, 128, 871, 424, 425, - 847, 896, -107, -107, -502, 71, 442, 443, 306, 311, - -107,-32766, 432, 433, -49, 141, -502, 1152, -508, 155, - 156, 780, 157, -84,-32766,-32766,-32766, 673,-32766, -76, - -32766, 873,-32766, 667, -149,-32766, 1216, 1216, 1179, 282, - -32766,-32766,-32766, -73, 73, -71,-32766,-32766, 311, -501, - -501, 129,-32766, 388, -70, -69,-32766, -504, -504, -68, - -32766, -67, 1152, -66, -501, -65, 871, -64, 275,-32766, - -32766,-32766, -504,-32766, -45,-32766, -501,-32766, -16, 861, - -32766, 145, -107, 264, -504,-32766,-32766,-32766, 682, 72, - 244,-32766,-32766,-32766, 685, 782, 674,-32766, 388, 1152, - 669, 871, -501, 870, 144,-32766,-32766,-32766,-32766, 272, - -32766, 282,-32766, 273,-32766, 73, 73,-32766, 1216, 311, - 311, 276,-32766,-32766,-32766, 885,-32766, 246,-32766,-32766, - 277, 677, 1152, 314,-32766, 388, -4, 871, 263,-32766, - -32766,-32766,-32766,-32766, 107,-32766, 143,-32766, 861, 778, - -32766, 871, 873,-32766, 667,-32766,-32766,-32766, 625, 647, - 871,-32766,-32766,-32766, -501, -501, 787,-32766, 388, 1152, - 1037,-32766, 969, 970, 1266,-32766,-32766,-32766,-32766, -501, - -32766, 531,-32766, 861,-32766, 660, 871,-32766, 630, 535, - 683, -501,-32766,-32766,-32766, 138,-32766, 642,-32766,-32766, - 1023, 311, 1152, 20,-32766, 388, 437, 466, 631,-32766, - -32766,-32766,-32766,-32766, 643,-32766, 286,-32766, -506, 861, - -32766, 913, 407, 667, 613,-32766,-32766,-32766,-32766, 284, - -467,-32766,-32766, 861, 46, 283, 282,-32766, 388, 686, - 897, 414, 861, 402, 898,-32766, 294, 38, 280, -232, - -232, -232, 496, 497, 1007, 414, 873, 26, 667, 1190, - 786, 806, 896, -107, -107, 1192, 496, 497, 861, 1216, - 47, -457, 8, 1183, 22, 847, 896, -107, -107, 347, - -506, -506, 541, 9, -231, -231, -231, 581, 1180, 887, - 414, 39, 873, 848, 667, -4, 289, 290, 689, 690, - 852, 496, 497, 937, 914, 1261, 873, -506, 667, -232, - 847, 896, -107, -107, 921, 873, 911, 667, 922, 850, - 909, -537, 502, 123, 1173, 1174, 1175, 1176, 1170, 1171, - 1012, 1015, 291, 292, 1016, 1013, 1177, 1172, 1014, 1020, - 1263, 873, 30, 667, -231, 304, 798, 348, 71, 1205, - 1223, 306, 311, 1257, 618, -535, 346, 668, -107, 125, - -107, 671, 675, 676, 678, 285, 679, 680, -107, -107, - -107, -107, -107, -107, -107, 684, 670, -257, 809, 808, - 817, 895, 929, 816, 1262, 894, 892, 893, 1138, 880, - 888, 878, 919, 920, 1260, 1217, 1206, 1224, 1230, 1233, - 0, -509, -508, -507, 1, 27, 28, 37, 41, 45, - 70, 74, -308, -255, 75, 76, 77, 78, 79, 140, - 149, 153, 239, 310, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 403, 404, 0, -254, 12, - 13, 14, 15, 17, 375, 457, 458, 465, 468, 469, - 470, 471, 475, 476, 477, 484, 654, 1163, 1106, 1181, - 984, 1142, -259, -99, 11, 16, 25, 279, 374, 574, - 578, 605, 659, 1110, 1158, 1107, 1236, 0, -471, 1123, - 0, 1184 + 322, 263,-32766,-32766,-32766, 104, 105, 106, 346, 263, + 952, 951, 950, 107, 350, 438, 439, 701,-32766,-32766, + -32766, 107, -253,-32766, 355,-32766,-32766,-32766,-32766,-32766, + -32766, 702, 703, 704, 705, 706, 707, 708, 452,-32766, + 770,-32766,-32766,-32766,-32766,-32766, 357, 709, 710, 711, + 712, 713, 714, 715, 716, 717, 718, 719, 739, 762, + 740, 741, 742, 743, 731, 732, 733, 761, 734, 735, + 720, 721, 722, 724, 725, 726, 764, 765, 766, 767, + 768, 769, 727, 728, 729, 730, 760, 751, 749, 750, + 746, 747, 619, 24, 738, 744, 745, 752, 753, 755, + 754, 756, 757, 524,-32766,-32766,-32766, 574, 748, 759, + 758, 48, 49, 50, 483, 51, 52, 147, 397, 580, + 408, 53, 54, 409, 55,-32766, 975,-32766,-32766,-32766, + -32766,-32766,-32766,-32767,-32767,-32767,-32767,-32767, 865,-32767, + -32767,-32767,-32767, 99, 100, 101, 102, 103, 1257, 410, + 1172, 1258, 411, 1145, 865, 271, 634, 635, 56, 57, + 148, 808, 1184, 809, 58, 453, 59, 240, 241, 60, + 61, 62, 63, 64, 65, 66, 67, 787, 26, 262, + 68, 412, 484, 121, 667,-32766, 1178, 1179, 485, 1143, + 781, 1147, 1146, 1148, 1176, 40, 23, 486, 1002, 487, + 150, 488, 234, 489, 962, 963, 490, 491, 780, 423, + 424, 42, 43, 413, 417, 415, 865, 44, 492, 151, + 855, 920, 248, 345, 321, 1152, 1147, 1146, 1148, 122, + 781, 493, 494, 495, 152, -330, 855, -330, 127, -505, + 960, 154, 496, 497, 35, 1166, 1167, 1168, 1169, 1163, + 1164, 280, 146, 377, 26, -14, 128, 1170, 1165, 962, + 963, 1147, 1146, 1148, 281, 141, 781, -501, 155, 69, + 1176, 305, 306, 309, 34, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 156, -149, + -149, -149, 478, 867, 18, 662, 1152, 1152, 855, 440, + 441, -505, -505, 157, -149, 781, -149, 138, -149, 867, + -149, 662, 808, 309, 809, 242, 1060, 1062, 496, 497, + 414, 1166, 1167, 1168, 1169, 1163, 1164, -500, -505, -501, + -501, -107, -107, 1170, 1165, -503, 1228, 865, 611, 612, + 841, -107, -107, -107, -501, 71, 921, -84, 306, 309, + -107,-32766, -76, 1001, -49, 686, -501, 1145, -507, -73, + -71, 774, -70, -69,-32766,-32766,-32766, 668,-32766, -68, + -32766, 867,-32766, 662, -149,-32766, 781, 781, -67, 281, + -32766,-32766,-32766, -66, 73, -65,-32766,-32766, 309, -500, + -500, 129,-32766, 388, -64, -45,-32766, -503, -503, -16, + -32766, 145, 1145, 264, -500, 676, 865, 679, 864,-32766, + -32766,-32766, -503,-32766, 772,-32766, -500,-32766, 144, 855, + -32766, 272, -107, 273, -503,-32766,-32766,-32766, 879, 72, + 244,-32766,-32766,-32766, 275, 776, 669,-32766, 388, 1145, + 664, 865, -500, 274, 276,-32766,-32766,-32766,-32766, 315, + -32766, 281,-32766, 263,-32766, 73, 73,-32766, 107, 309, + 309, 143,-32766,-32766,-32766, 642,-32766, 246,-32766,-32766, + 532, 671, 1145, 772,-32766, 388, -4, 865, 1259,-32766, + -32766,-32766,-32766,-32766, 781,-32766,-32766,-32766, 855, 1030, + -32766, 865, 867, 139, 662,-32766,-32766,-32766, 655, 309, + 865,-32766,-32766,-32766, -500, -500, 526,-32766, 388, 1145, + 101, 102, 103, 620, 637,-32766,-32766,-32766,-32766, -500, + -32766, 960,-32766, 855,-32766, 20, 865,-32766,-32766, 625, + 677, -500,-32766,-32766,-32766, 435,-32766, 463,-32766,-32766, + 962, 963, 1145, 626,-32766, 388, 638, 962, 963,-32766, + -32766,-32766,-32766,-32766, 609,-32766, 289,-32766, 46, 855, + -32766, 906, 407, 662,-32766,-32766,-32766,-32766, 287, 1016, + 1183,-32766,-32766, 855, 286, 293, 781,-32766, 388, 1247, + 890, 414, 855, 402, 891,-32766, 881, 538, 279, -231, + -231, -231, -107, -107, 1000, 414, 867, 26, 662, 1185, + 578, 800, -107, -107, -107, -466, -107, -107, 855, 781, + 47, -456, 7, 1176, 22, 841, -107, -107, -107, 348, + 282, 283, 780, 9, -230, -230, -230, 281, 1173, -536, + 414, 38, 867, 39, 662, -4, 683, 684, 846, 32, + 243, -107, -107, 930, 907, 680, 867, 123, 662, -231, + 841, -107, -107, -107, 914, 867, 904, 662, 915, 844, + 902, 1005, 497, 1008, 1166, 1167, 1168, 1169, 1163, 1164, + 1009, 1006, 284, 285, 1007, 1013, 1170, 1165, 792, 1198, + 1216, 867, 30, 662, -230, 304, 1250, 349, 71, 614, + 842, 306, 309, 347, 663, 666, 670, 672, -107, 125, + -107, 673, 674, 678, 665, 288, 1254, 1256, -107, -107, + -107, -107, -107, -107, -107, 803, 802, 811, 888, 922, + 810, 1255, 887, 886, 1131, 874, 882, 872, 912, 913, + 1253, 1210, 1199, 1217, 1223, 1226, 0, -534, -508, -507, + -506, 1, 27, 28, 37, 41, 45, 70, 74, 75, + 76, 77, -307, -256, 78, 79, 140, 149, 153, 239, + 311, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 403, 404, 0, -254, -253, 12, 13, 14, + 15, 17, 376, 454, 455, 462, 465, 466, 467, 468, + 472, 473, 474, 481, 649, 1156, 1099, 1174, 977, 1135, + -258, -99, 11, 16, 25, 278, 375, 571, 575, 601, + 654, 1103, 1151, 1100, 1229, 0, -470, 1116, 0, 1177, + 0, 309 ); protected $actionCheck = array( - 2, 3, 4, 5, 6, 7, 115, 9, 10, 11, - 12, 13, 157, 1, 31, 73, 161, 9, 10, 11, - 8, 79, 79, 31, 1, 134, 135, 0, 86, 87, - 88, 8, 90, 1, 92, 37, 94, 1, 30, 97, + 2, 3, 4, 5, 6, 7, 0, 9, 10, 11, + 12, 13, 1, 116, 117, 73, 1, 9, 10, 11, + 1, 79, 79, 126, 127, 128, 1, 8, 86, 87, + 88, 8, 90, 8, 92, 37, 94, 8, 30, 97, 32, 33, 34, 101, 102, 103, 104, 9, 10, 11, - 108, 109, 14, 105, 56, 107, 114, 115, 115, 116, - 117, 118, 119, 120, 122, 105, 106, 8, 70, 71, - 72, 73, 74, 75, 76, 115, 1, 79, 115, 116, + 108, 109, 14, 1, 56, 79, 114, 115, 115, 116, + 117, 118, 119, 120, 122, 105, 106, 1, 70, 71, + 72, 73, 74, 75, 76, 115, 8, 79, 115, 116, 117, 118, 119, 120, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 8, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 153, 8, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 1, 158, 79, 69, 1, 147, 148, 149, 156, 151, + 157, 1, 8, 69, 161, 147, 148, 149, 8, 151, 9, 10, 11, 2, 3, 4, 5, 6, 7, 161, - 9, 10, 11, 12, 13, 9, 10, 11, 73, 157, - 9, 10, 11, 161, 79, 80, 49, 50, 51, 50, - 157, 86, 87, 88, 161, 90, 30, 92, 37, 94, - 158, 30, 97, 32, 33, 34, 35, 102, 103, 104, - 118, 119, 120, 108, 109, 131, 132, 56, 79, 114, - 115, 82, 9, 10, 11, 14, 153, 122, 79, 8, - 146, 70, 71, 72, 73, 74, 75, 76, 9, 10, - 79, 156, 158, 30, 160, 32, 33, 86, 87, 88, + 9, 10, 11, 12, 13, 9, 10, 11, 73, 158, + 9, 10, 11, 158, 79, 80, 157, 9, 10, 164, + 161, 86, 87, 88, 161, 90, 30, 92, 37, 94, + 161, 30, 97, 32, 33, 34, 35, 102, 103, 104, + 8, 105, 106, 108, 109, 131, 132, 56, 156, 114, + 115, 115, 9, 10, 11, 14, 8, 122, 31, 8, + 146, 70, 71, 72, 73, 74, 75, 76, 8, 161, + 79, 8, 158, 30, 160, 32, 33, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 161, 161, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 69, 9, 10, 11, 158, 147, 148, - 149, 158, 151, 2, 3, 4, 5, 6, 7, 1, + 129, 130, 8, 96, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 69, 9, 10, 11, 157, 147, 148, + 149, 161, 151, 2, 3, 4, 5, 6, 7, 9, 9, 10, 11, 12, 13, 30, 8, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 8, 56, 9, 10, 11, 52, 53, 54, 1, 56, - 81, 8, 8, 68, 8, 131, 132, 56, 9, 10, + 8, 56, 9, 10, 11, 52, 53, 54, 8, 56, + 118, 119, 120, 68, 8, 131, 132, 56, 9, 10, 11, 68, 161, 30, 8, 32, 33, 34, 35, 36, - 37, 70, 71, 72, 73, 74, 75, 76, 8, 30, + 37, 70, 71, 72, 73, 74, 75, 76, 31, 30, 79, 32, 33, 34, 35, 36, 8, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 84, 164, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 96, 9, 10, 11, 8, 147, 148, - 149, 2, 3, 4, 5, 6, 7, 105, 79, 107, + 129, 130, 74, 75, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 84, 9, 10, 11, 1, 147, 148, + 149, 2, 3, 4, 5, 6, 7, 14, 79, 50, 8, 12, 13, 8, 15, 30, 1, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 8, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 105, 8, - 107, 143, 8, 79, 1, 30, 8, 1, 49, 50, - 8, 105, 8, 107, 55, 161, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 9, 69, 70, - 71, 72, 73, 8, 31, 115, 77, 78, 79, 115, + 35, 36, 37, 38, 39, 40, 41, 42, 1, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 79, 8, + 1, 82, 8, 79, 1, 30, 74, 75, 49, 50, + 14, 105, 143, 107, 55, 158, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 8, 69, 70, + 71, 72, 73, 16, 31, 115, 77, 78, 79, 115, 81, 152, 153, 154, 85, 86, 87, 88, 159, 90, - 31, 92, 14, 94, 134, 135, 97, 98, 152, 105, - 106, 102, 103, 104, 105, 106, 1, 108, 109, 115, - 116, 117, 37, 114, 115, 1, 152, 153, 154, 8, - 126, 122, 123, 124, 14, 156, 83, 158, 81, 83, - 115, 84, 133, 134, 14, 136, 137, 138, 139, 140, - 141, 142, 74, 75, 69, 31, 14, 148, 149, 134, - 135, 152, 153, 154, 155, 96, 81, 69, 14, 160, + 14, 92, 96, 94, 134, 135, 97, 98, 152, 105, + 106, 102, 103, 104, 105, 106, 1, 108, 109, 14, + 83, 31, 37, 114, 115, 1, 152, 153, 154, 16, + 81, 122, 123, 124, 14, 105, 83, 107, 16, 69, + 115, 14, 133, 134, 14, 136, 137, 138, 139, 140, + 141, 142, 100, 101, 69, 31, 16, 148, 149, 134, + 135, 152, 153, 154, 155, 16, 81, 69, 16, 160, 85, 162, 163, 164, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 14, 74, - 75, 76, 74, 75, 100, 101, 1, 1, 83, 110, - 111, 144, 145, 14, 89, 81, 91, 16, 93, 156, - 95, 158, 156, 16, 158, 37, 58, 59, 133, 134, - 105, 136, 137, 138, 139, 140, 141, 69, 16, 131, - 132, 116, 117, 148, 149, 69, 16, 1, 105, 106, - 125, 126, 127, 128, 146, 160, 105, 106, 163, 164, - 126, 73, 127, 128, 31, 16, 158, 79, 160, 16, - 16, 79, 16, 31, 86, 87, 88, 31, 90, 31, - 92, 156, 94, 158, 159, 97, 81, 81, 1, 155, + 22, 23, 24, 25, 26, 27, 28, 29, 16, 74, + 75, 76, 105, 156, 107, 158, 1, 1, 83, 105, + 106, 131, 132, 16, 89, 81, 91, 158, 93, 156, + 95, 158, 105, 164, 107, 37, 58, 59, 133, 134, + 105, 136, 137, 138, 139, 140, 141, 69, 158, 131, + 132, 116, 117, 148, 149, 69, 1, 1, 110, 111, + 125, 126, 127, 128, 146, 160, 156, 31, 163, 164, + 126, 73, 31, 156, 31, 158, 158, 79, 160, 31, + 31, 79, 31, 31, 86, 87, 88, 31, 90, 31, + 92, 156, 94, 158, 159, 97, 81, 81, 31, 155, 102, 103, 104, 31, 160, 31, 108, 109, 164, 131, 132, 31, 114, 115, 31, 31, 73, 131, 132, 31, - 122, 31, 79, 31, 146, 31, 1, 31, 30, 86, - 87, 88, 146, 90, 31, 92, 158, 94, 31, 83, - 97, 31, 126, 31, 158, 102, 103, 104, 31, 151, - 37, 108, 109, 73, 31, 153, 31, 114, 115, 79, - 158, 1, 69, 31, 31, 122, 86, 87, 88, 35, - 90, 155, 92, 35, 94, 160, 160, 97, 81, 164, - 164, 35, 102, 103, 104, 37, 73, 37, 108, 109, - 35, 31, 79, 35, 114, 115, 0, 1, 56, 86, - 87, 88, 122, 90, 68, 92, 69, 94, 83, 79, - 97, 1, 156, 115, 158, 102, 103, 104, 89, 76, - 1, 108, 109, 73, 131, 132, 81, 114, 115, 79, - 81, 84, 134, 135, 82, 122, 86, 87, 88, 146, - 90, 84, 92, 83, 94, 91, 1, 97, 95, 88, - 31, 158, 102, 103, 104, 158, 73, 93, 108, 109, - 121, 164, 79, 96, 114, 115, 96, 96, 99, 86, - 87, 88, 122, 90, 99, 92, 113, 94, 69, 83, - 97, 156, 126, 158, 112, 102, 103, 104, 115, 130, - 146, 108, 109, 83, 69, 129, 155, 114, 115, 159, - 126, 105, 83, 107, 126, 122, 129, 156, 112, 99, + 122, 31, 79, 31, 146, 31, 1, 31, 31, 86, + 87, 88, 146, 90, 79, 92, 158, 94, 31, 83, + 97, 35, 126, 35, 158, 102, 103, 104, 37, 151, + 37, 108, 109, 73, 35, 153, 31, 114, 115, 79, + 158, 1, 69, 30, 35, 122, 86, 87, 88, 35, + 90, 155, 92, 56, 94, 160, 160, 97, 68, 164, + 164, 69, 102, 103, 104, 76, 73, 37, 108, 109, + 88, 31, 79, 79, 114, 115, 0, 1, 82, 86, + 87, 88, 122, 90, 81, 92, 84, 94, 83, 81, + 97, 1, 156, 158, 158, 102, 103, 104, 91, 164, + 1, 108, 109, 73, 131, 132, 84, 114, 115, 79, + 49, 50, 51, 89, 93, 122, 86, 87, 88, 146, + 90, 115, 92, 83, 94, 96, 1, 97, 115, 95, + 31, 158, 102, 103, 104, 96, 73, 96, 108, 109, + 134, 135, 79, 99, 114, 115, 99, 134, 135, 86, + 87, 88, 122, 90, 112, 92, 113, 94, 69, 83, + 97, 156, 126, 158, 115, 102, 103, 104, 130, 121, + 143, 108, 109, 83, 129, 129, 81, 114, 115, 84, + 126, 105, 83, 107, 126, 122, 151, 150, 112, 99, 100, 101, 116, 117, 1, 105, 156, 69, 158, 143, - 152, 125, 126, 127, 128, 143, 116, 117, 83, 81, + 150, 125, 126, 127, 128, 146, 116, 117, 83, 81, 69, 146, 146, 85, 146, 125, 126, 127, 128, 146, - 131, 132, 150, 147, 99, 100, 101, 150, 157, 151, - 105, 156, 156, 159, 158, 159, 131, 132, 156, 156, - 156, 116, 117, 156, 156, 159, 156, 158, 158, 159, + 131, 132, 152, 147, 99, 100, 101, 155, 157, 160, + 105, 156, 156, 156, 158, 159, 156, 156, 156, 144, + 145, 116, 117, 156, 156, 159, 156, 158, 158, 159, 125, 126, 127, 128, 156, 156, 156, 158, 156, 156, - 156, 160, 134, 158, 136, 137, 138, 139, 140, 141, - 156, 156, 131, 132, 156, 156, 148, 149, 156, 156, - 159, 156, 158, 158, 159, 158, 157, 146, 160, 157, - 157, 163, 164, 157, 157, 160, 158, 158, 105, 158, - 107, 158, 158, 158, 158, 112, 158, 158, 115, 116, - 117, 118, 119, 120, 121, 158, 158, 161, 159, 159, + 156, 156, 134, 156, 136, 137, 138, 139, 140, 141, + 156, 156, 131, 132, 156, 156, 148, 149, 157, 157, + 157, 156, 158, 158, 159, 158, 157, 146, 160, 157, + 159, 163, 164, 158, 158, 158, 158, 158, 105, 158, + 107, 158, 158, 158, 158, 112, 159, 159, 115, 116, + 117, 118, 119, 120, 121, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, - 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, - -1, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 159, 159, 159, 159, 159, 159, -1, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 159, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, -1, 161, 161, + 160, 160, 160, 160, -1, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, -1, 162, 162, - -1, 163 + 161, 161, 161, 161, 161, -1, 162, 162, -1, 163, + -1, 164 ); protected $actionBase = array( - 0, -2, 151, 555, 816, 830, 865, 379, 717, 622, - 862, 676, 780, 780, 839, 780, 493, 745, 301, 301, - -57, 301, 301, 496, 496, 496, 618, 618, 618, 618, + 0, -2, 151, 555, 816, 830, 865, 489, 379, 622, + 858, 676, 780, 780, 839, 780, 493, 745, 301, 301, + -57, 301, 301, 477, 477, 477, 618, 618, 618, 618, -58, -58, 95, 700, 733, 770, 663, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, @@ -496,63 +496,63 @@ class Php7 extends \PhpParser\ParserAbstract 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, - 803, 803, 803, 803, 803, 803, 803, 803, 75, -8, - 347, 629, 986, 992, 988, 993, 984, 983, 987, 989, - 994, 915, 916, 753, 917, 918, 919, 920, 990, 877, - 985, 991, 285, 285, 285, 285, 285, 285, 285, 285, + 803, 803, 803, 803, 803, 803, 803, 803, 52, 530, + 446, 570, 984, 990, 986, 991, 982, 981, 985, 987, + 992, 911, 912, 727, 913, 914, 915, 916, 988, 872, + 983, 989, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, - 285, 285, 285, 508, 38, 219, 141, 141, 141, 141, + 285, 285, 285, 300, 38, 168, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 156, 156, 156, 203, 525, 525, 8, 598, 161, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 349, 333, 435, 435, 435, 435, 435, 436, 436, 436, 436, - 933, 564, 636, 635, 465, -52, 127, 127, 718, 718, - 759, 410, 410, 410, 444, -109, -109, -109, 74, 538, - 396, 348, 414, 414, 414, 414, 414, 802, 998, 139, - 139, 139, 139, 414, 414, 414, 606, 713, 713, 881, - 293, 293, 293, 713, 383, 777, 497, 383, 497, 129, - 793, 32, -40, -145, 793, 829, 845, 23, 12, 788, - 573, 788, 767, 863, 898, 995, 82, 789, 913, 795, - 914, 224, 678, 981, 981, 981, 981, 981, 981, 981, - 981, 981, 981, 981, 269, 982, 63, 269, 269, 269, - 529, 63, 518, 558, 63, 778, 982, 75, 805, 75, - 75, 75, 75, 944, 75, 75, 75, 75, 75, 75, - 949, 727, 723, 692, -17, 75, -8, 143, 143, 419, - 36, 143, 143, 143, 143, 75, 75, 565, 573, 762, - 812, 581, 817, 344, 762, 762, 762, 509, 121, 201, - 122, 352, 750, 750, 768, 769, 924, 924, 750, 765, - 750, 769, 929, 750, 768, 768, 750, 924, 768, 761, - 343, 488, 452, 470, 768, 768, 492, 924, 370, 768, - 768, 750, 750, 750, 797, 768, 494, 750, 356, 346, - 750, 750, 768, 768, 797, 786, 59, 779, 924, 924, - 924, 797, 455, 779, 779, 822, 823, 792, 732, 439, - 378, 561, 332, 768, 732, 732, 750, 481, 792, 732, - 792, 732, 818, 732, 732, 732, 792, 732, 765, 484, - 732, 768, 515, 211, 732, 27, 930, 931, 672, 934, - 927, 935, 955, 936, 937, 879, 794, 798, 942, 928, - 938, 926, 925, 752, 631, 637, 806, 764, 923, 756, - 756, 756, 921, 756, 756, 756, 756, 756, 756, 756, - 756, 631, 811, 813, 776, 781, 945, 652, 660, 796, - 814, 996, 997, 944, 976, 939, 771, 679, 962, 946, - 760, 867, 947, 948, 963, 977, 978, 826, 757, 861, - 899, 869, 950, 883, 756, 930, 937, 928, 938, 926, - 925, 716, 714, 710, 712, 708, 704, 694, 703, 730, - 875, 841, 872, 949, 922, 631, 873, 958, 864, 964, - 965, 878, 790, 772, 876, 900, 951, 952, 953, 884, - 979, 885, 815, 959, 896, 966, 791, 901, 967, 968, - 969, 970, 886, 902, 888, 824, 749, 932, 773, 903, - 528, 766, 775, 956, 560, 943, 889, 904, 905, 971, - 972, 973, 906, 907, 940, 827, 960, 784, 961, 957, - 828, 838, 570, 754, 758, 582, 594, 908, 909, 941, - 737, 763, 840, 842, 980, 910, 614, 843, 683, 911, - 975, 684, 686, 774, 897, 808, 783, 787, 954, 743, - 844, 912, 854, 855, 858, 974, 859, 0, 0, 0, + 933, 564, 636, 635, 465, 470, 801, 801, 753, 753, + 788, 746, 746, 746, 410, 410, 410, 74, 538, 396, + 359, 414, 675, 675, 675, 675, 414, 414, 414, 414, + 796, 996, 414, 414, 414, -103, 606, 713, 713, 881, + 293, 293, 293, 713, 547, 762, 835, 547, 835, 15, + 409, 789, -40, 96, -17, 789, 510, 829, 140, 19, + 810, 444, 810, 742, 859, 886, 993, 232, 784, 909, + 787, 910, 224, 661, 979, 979, 979, 979, 979, 979, + 979, 979, 979, 979, 979, 997, 980, -24, 997, 997, + 997, 568, -24, 358, 422, -24, 754, 980, 52, 805, + 52, 52, 52, 52, 941, 52, 52, 52, 52, 52, + 52, 946, 708, 704, 668, 347, 52, 530, 11, 11, + 537, 66, 11, 11, 11, 11, 52, 52, 444, 737, + 777, 534, 790, 68, 737, 737, 737, 187, 23, 201, + 29, 527, 734, 734, 731, 748, 921, 921, 734, 743, + 734, 748, 926, 734, 731, 731, 921, 731, 812, 208, + 452, 332, 346, 731, 731, 455, 921, 223, 731, 731, + 734, 734, 734, 731, 481, 734, 220, 211, 734, 734, + 731, 731, 785, 786, 122, 921, 921, 921, 786, 340, + 778, 778, 820, 821, 782, 712, 308, 274, 509, 192, + 731, 712, 712, 734, 356, 782, 712, 782, 712, 775, + 712, 712, 712, 782, 712, 743, 378, 712, 731, 484, + 134, 712, 6, 927, 928, 656, 929, 924, 930, 952, + 931, 934, 876, 939, 925, 935, 923, 922, 717, 507, + 553, 806, 799, 920, 730, 730, 730, 918, 730, 730, + 730, 730, 730, 730, 730, 730, 507, 811, 813, 776, + 722, 942, 562, 580, 767, 871, 994, 995, 794, 798, + 941, 974, 936, 815, 589, 960, 943, 826, 867, 944, + 945, 961, 975, 976, 887, 732, 888, 896, 861, 947, + 877, 730, 927, 934, 925, 935, 923, 922, 703, 694, + 687, 692, 678, 672, 669, 671, 710, 917, 809, 862, + 946, 919, 507, 863, 956, 864, 962, 963, 875, 779, + 736, 869, 897, 948, 949, 950, 878, 977, 817, 957, + 932, 964, 781, 898, 965, 966, 967, 968, 899, 879, + 883, 822, 764, 954, 774, 900, 443, 739, 749, 953, + 486, 940, 884, 901, 902, 969, 970, 971, 903, 937, + 827, 958, 761, 959, 955, 828, 838, 526, 726, 728, + 545, 560, 904, 905, 938, 714, 729, 840, 842, 978, + 906, 567, 843, 592, 907, 973, 612, 627, 747, 885, + 808, 783, 769, 951, 716, 844, 908, 845, 847, 854, + 972, 855, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 449, 449, 449, 449, 449, - 449, 301, 301, 301, 301, 449, 449, 449, 449, 449, - 449, 449, 0, 0, 301, 0, 0, 449, 449, 449, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 449, + 449, 449, 449, 449, 449, 301, 301, 301, 301, 449, + 449, 449, 449, 449, 449, 449, 0, 0, 301, 0, + 0, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, @@ -565,41 +565,40 @@ class Php7 extends \PhpParser\ParserAbstract 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 285, 285, 285, 285, 285, 285, 285, 285, - 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, - 285, 285, 285, 285, 285, 285, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 285, 285, 285, + 449, 449, 449, 449, 449, 449, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, - 285, 285, 285, 285, 285, 285, 285, 285, 414, 414, - 285, 0, 285, 414, 414, 414, 414, 414, 414, 414, - 414, 414, 414, 285, 285, 285, 285, 285, 285, 285, - 293, 293, 293, 293, 761, 414, 414, 414, 414, -37, - 293, 293, 414, 414, -37, 414, 414, 414, 761, 414, - 414, 414, 0, 0, 63, 497, 0, 0, 0, 0, - 0, 497, 497, 269, 269, 269, 269, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 63, 497, - 0, 63, 0, 765, 414, 269, 761, 308, 414, 0, - 0, 0, 0, 63, 765, 63, 497, 143, 75, 308, - 0, 534, 534, 534, 534, 0, 573, 761, 761, 761, - 761, 761, 761, 761, 761, 761, 761, 761, 0, 761, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 765, - 768, 0, 924, 0, 0, 0, 0, 750, 0, 0, - 0, 0, 0, 0, 750, 929, 768, 768, 0, 0, - 0, 0, 0, 0, 765, 0, 0, 0, 0, 0, - 0, 0, 0, 756, 790, 0, 790, 0, 756, 756, - 756 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 285, 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 414, 414, 285, 0, 285, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 285, 285, 285, + 285, 285, 285, 285, 293, 293, 293, 293, 812, 414, + 414, 414, 414, -37, 293, 293, 414, 414, -37, 414, + 414, 414, 414, 414, 414, 0, 0, -24, 835, 0, + 743, 743, 743, 743, 0, 0, 0, 0, 835, 835, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -24, 835, 0, -24, 0, 743, 743, 414, + 812, 812, 25, 414, 0, 0, 0, 0, -24, 743, + -24, 835, 11, 52, 25, 0, 492, 492, 492, 492, + 0, 444, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 743, 812, 0, 743, 743, 743, 0, + 0, 0, 0, 0, 743, 731, 0, 921, 0, 0, + 0, 0, 734, 0, 0, 0, 0, 0, 0, 734, + 926, 731, 731, 0, 0, 0, 0, 0, 0, 743, + 0, 0, 0, 0, 0, 0, 0, 730, 779, 0, + 779, 0, 730, 730, 730 ); protected $actionDefault = array( 3,32767, 99,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767, 97, - 32767,32767,32767,32767,32767,32767, 555, 555, 555, 555, - 236, 99,32767,32767,32767,32767, 431, 350, 350, 350, - 32767,32767, 499, 499, 499, 499, 499, 499,32767,32767, - 32767,32767,32767,32767, 431,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 554, 554, 554, 554, + 235, 99,32767,32767,32767,32767, 430, 349, 349, 349, + 32767,32767, 498, 498, 498, 498, 498, 498,32767,32767, + 32767,32767,32767,32767, 430,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, @@ -610,129 +609,125 @@ class Php7 extends \PhpParser\ParserAbstract 35, 5, 6, 8, 9, 48, 15,32767,32767,32767, 32767,32767, 99,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767, 548,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 547,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767, 435, 414, 415, 417, 418, 349, 500, 554, - 293, 551, 348, 142, 305, 295, 224, 296, 240, 241, - 267, 345, 146, 379, 432, 381, 430, 434, 380, 355, - 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 353, 354, 433, 436, 437, 440, 441, - 411, 410, 409, 377,32767,32767, 378, 352, 382,32767, - 32767,32767,32767,32767,32767,32767,32767, 99,32767, 384, - 383, 400, 401, 398, 399, 402, 403, 404, 405, 406, - 32767,32767,32767,32767,32767, 328, 391, 392, 284, 284, - 330,32767,32767,32767, 108,32767,32767,32767, 493, 408, + 32767,32767, 434, 413, 414, 416, 417, 348, 499, 553, + 292, 550, 347, 142, 304, 294, 223, 295, 239, 240, + 266, 344, 146, 378, 431, 380, 429, 433, 379, 354, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, 370, 371, 352, 353, 432, 435, 436, 439, 440, + 410, 409, 408, 376,32767,32767, 377, 351, 381,32767, + 32767,32767,32767,32767,32767,32767,32767, 99,32767, 383, + 382, 399, 400, 397, 398, 401, 402, 403, 404, 405, + 32767,32767,32767,32767,32767, 327, 390, 391, 283, 283, + 329,32767,32767,32767,32767,32767,32767, 492, 407,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767, 99,32767, 97, 495, 374, 376, 463, - 386, 387, 385, 356,32767, 470,32767, 99, 472,32767, - 32767,32767,32767,32767,32767, 494,32767, 501, 501,32767, - 456, 97,32767,32767,32767,32767, 262,32767,32767,32767, - 32767, 562, 456, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107,32767, 107,32767,32767,32767, 97, - 185,32767, 250, 252, 99, 516, 190,32767, 475,32767, + 32767,32767, 99,32767, 97,32767, 494, 373, 375, 462, + 385, 386, 384, 355,32767, 469,32767, 99, 471,32767, + 32767,32767, 108,32767,32767,32767, 493,32767, 500, 500, + 32767, 455, 97,32767,32767,32767,32767, 261,32767,32767, + 32767,32767, 561, 455, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107,32767, 107,32767,32767,32767, + 97, 185,32767, 249, 251, 99, 515, 190,32767, 474, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767, 468, 190, 190,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767,32767, 456, 396, - 135,32767, 135, 501, 388, 389, 390, 458, 501, 501, - 501,32767,32767,32767, 190,32767, 473, 473, 97, 97, - 97, 97, 468,32767, 190, 190,32767,32767, 190, 108, - 96, 96, 96, 96, 190, 190, 96, 100, 98, 190, - 190,32767,32767,32767, 205, 190, 96,32767, 98, 98, - 32767,32767, 190, 190, 205, 207, 98, 209,32767, 520, - 521, 205, 98, 209, 209, 229, 229, 447, 286, 98, - 96, 98, 98, 190, 286, 286,32767, 98, 447, 286, - 447, 286, 192, 286, 286, 286, 447, 286,32767, 98, - 286, 190, 96, 96, 286,32767,32767,32767, 458,32767, + 32767,32767, 467, 190, 190,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767, 455, 395, + 135,32767, 135, 500, 387, 388, 389, 457, 500, 500, + 500,32767,32767,32767, 190,32767, 472, 472, 97, 97, + 97, 97, 467,32767, 190, 190,32767, 190, 108, 96, + 96, 96, 96, 190, 190, 96, 100, 98, 190, 190, + 32767,32767,32767, 190, 96,32767, 98, 98,32767,32767, + 190, 190, 206, 204, 98,32767, 519, 520, 204, 98, + 208, 208, 228, 228, 446, 285, 98, 96, 98, 98, + 190, 285, 285,32767, 98, 446, 285, 446, 285, 192, + 285, 285, 285, 446, 285,32767, 98, 285, 190, 96, + 96, 285,32767,32767,32767, 457,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767, 488,32767, 505, 518, 394, - 395, 397, 503, 419, 420, 421, 422, 423, 424, 425, - 427, 550,32767, 462,32767,32767,32767,32767, 304, 560, - 32767, 560,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767, 561,32767, 501, - 32767,32767,32767,32767, 393, 7, 74, 41, 42, 50, - 56, 479, 480, 481, 482, 476, 477, 483, 478,32767, - 484, 526,32767,32767, 502, 553,32767,32767,32767,32767, - 32767,32767, 135,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767, 488,32767, 133,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767, 501,32767,32767, - 32767, 281, 283,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767,32767,32767, 501, - 32767,32767,32767, 269, 271,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767,32767, 266,32767, - 32767, 344,32767,32767,32767,32767, 324,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767, 148, 148, 3, - 3, 307, 148, 148, 148, 307, 307, 148, 307, 307, - 148, 148, 148, 148, 148, 148, 180, 244, 247, 229, - 229, 148, 316, 148 + 487,32767, 504, 517, 393, 394, 396, 502, 418, 419, + 420, 421, 422, 423, 424, 426, 549,32767, 461,32767, + 32767,32767,32767, 303, 559,32767, 559,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767, 560,32767, 500,32767,32767,32767, + 32767, 392, 7, 74, 41, 42, 50, 56, 478, 479, + 480, 481, 475, 476, 482, 477,32767, 483, 525,32767, + 32767, 501, 552,32767,32767,32767,32767,32767,32767, 135, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 487,32767, 133,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767, 500,32767,32767,32767, 280, 282,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767, 500,32767,32767,32767, 268, 270, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767, 265,32767,32767, 343,32767,32767,32767, + 32767, 323,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767, 148, 148, 3, 3, 306, 148, 148, 148, + 306, 148, 306, 306, 148, 148, 148, 148, 148, 148, + 180, 243, 246, 228, 228, 148, 315, 148 ); protected $goto = array( - 190, 190, 655, 781, 663, 399, 629, 964, 971, 972, - 393, 297, 298, 317, 549, 303, 398, 318, 400, 607, - 361, 365, 534, 572, 576, 161, 161, 161, 161, 187, + 190, 190, 650, 1020, 979, 399, 624, 798, 1019, 658, + 393, 297, 298, 318, 546, 303, 398, 319, 400, 603, + 362, 366, 531, 569, 573, 161, 161, 161, 161, 187, 187, 171, 173, 209, 191, 204, 187, 187, 187, 187, 187, 188, 188, 188, 188, 188, 188, 182, 183, 184, - 185, 186, 206, 204, 207, 509, 510, 389, 511, 513, - 514, 515, 516, 517, 518, 519, 520, 1053, 162, 163, + 185, 186, 206, 204, 207, 504, 505, 389, 506, 508, + 509, 510, 511, 512, 513, 514, 515, 1046, 162, 163, 164, 189, 165, 166, 167, 160, 168, 169, 170, 172, 203, 205, 208, 230, 233, 236, 238, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 266, 267, - 300, 301, 302, 394, 395, 396, 554, 210, 211, 212, + 300, 301, 302, 394, 395, 396, 551, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 174, 225, 175, 192, 193, 194, 231, 182, - 183, 184, 185, 186, 206, 1053, 195, 176, 177, 178, + 183, 184, 185, 186, 206, 1046, 195, 176, 177, 178, 196, 192, 179, 232, 197, 159, 198, 226, 180, 199, - 227, 228, 181, 229, 200, 201, 202, 807, 611, 611, - 804, 274, 274, 274, 274, 976, 973, 974, 592, 626, - 1147, 594, 594, 571, 533, 526, 1182, 1182, 1182, 1182, - 1182, 1182, 1182, 1182, 1182, 1182, 1250, 1250, 986, 328, - 812, 1027, 860, 855, 856, 869, 1026, 813, 857, 810, - 858, 859, 811, 803, 1251, 1251, 805, 1250, 863, 912, - 936, 910, 910, 908, 910, 687, 363, 526, 1003, 1004, - 533, 1253, 525, 945, 940, 1251, 542, 543, 820, 1148, - 838, 370, 552, 832, 308, 288, 819, 573, 864, 795, - 865, 1200, 1200, 785, 587, 588, 1200, 1200, 1200, 1200, - 1200, 1200, 1200, 1200, 1200, 1200, 1151, 1151, 1151, 968, - 1149, 1208, 1209, 968, 968, 472, 968, 968, 968, 779, - 968, 968, 968, 1232, 1232, 1232, 1232, 1151, 1151, 1151, - 1151, 1151, 785, 21, 785, 546, 1198, 1198, 1151, 1151, - 1151, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, - 1198, 523, 523, 523, 325, 876, 512, 512, 392, 877, - 582, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 1240, 427, 906, 906, 906, 906, 387, 387, 387, - 387, 602, 604, 427, 900, 907, 540, 904, 379, 662, - 688, 606, 608, 933, 5, 627, 6, 539, 645, 649, - 947, 653, 661, 943, 586, 377, 378, 800, 1019, 570, - 635, 666, 636, 359, 381, 382, 383, 453, 646, 652, - 652, 384, 658, 1017, 454, 323, 580, 595, 598, 599, - 600, 601, 619, 620, 621, 665, 527, 537, 1267, 450, - 1225, 1226, 527, 545, 537, 800, 628, 362, 1101, 528, - 434, 521, 521, 521, 521, 1227, 1228, 1132, 890, 405, - 575, 1133, 1136, 891, 1137, 444, 553, 445, 419, 419, - 419, 830, 329, 330, 1258, 1259, 1222, 1222, 1222, 622, - 623, 431, 637, 638, 1211, 439, 439, 550, 585, 881, - 1041, 797, 319, 833, 821, 991, 439, 590, 995, 825, - 828, 369, 822, 952, 1234, 1234, 1234, 1234, 915, 648, - 824, 955, 632, 931, 473, 691, 474, 992, 818, 1144, - 451, 996, 480, 0, 834, 1036, 1218, 917, 0, 0, - 1143, 0, 905, 0, 0, 0, 0, 0, 528, 0, - 0, 419, 419, 419, 419, 419, 419, 419, 419, 419, - 419, 419, 800, 419, 1034, 837, 0, 0, 0, 994, - 0, 0, 1220, 1220, 994, 0, 0, 0, 0, 0, + 227, 228, 181, 229, 200, 201, 202, 312, 312, 312, + 312, 801, 577, 591, 594, 595, 596, 597, 615, 616, + 617, 660, 799, 329, 530, 521, 590, 590, 568, 794, + 794, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, + 1175, 858, 779, 859, 806, 775, 854, 849, 850, 863, + 905, 807, 851, 804, 852, 853, 805, 295, 295, 295, + 295, 832, 857, 607, 607, 364, 521, 773, 530, 969, + 966, 967, 996, 997, 539, 540, 957, 964, 965, 371, + 549, 588, 621, 779, 570, 779, 1244, 1244, 1193, 1193, + 543, 584, 585, 1193, 1193, 1193, 1193, 1193, 1193, 1193, + 1193, 1193, 1193, 326, 1244, 1144, 1144, 1144, 961, 1140, + 1233, 469, 961, 961, 926, 961, 961, 961, 961, 961, + 961, 1225, 1225, 1225, 1225, 1144, 470, 360, 471, 21, + 1144, 1144, 1144, 1144, 477, 794, 1144, 1144, 1144, 332, + 437, 437, 567, 1012, 618, 661, 632, 633, 542, 332, + 332, 437, 623, 647, 647, 870, 653, 1010, 1094, 871, + 447, 1218, 1219, 814, 332, 332, 1141, 332, 826, 1260, + 5, 813, 6, 518, 518, 518, 789, 320, 1191, 1191, + 523, 791, 332, 1191, 1191, 1191, 1191, 1191, 1191, 1191, + 1191, 1191, 1191, 426, 405, 1142, 1201, 1202, 899, 899, + 899, 899, 370, 536, 426, 893, 900, 897, 380, 657, + 583, 507, 507, 308, 291, 1204, 507, 507, 507, 507, + 507, 507, 507, 507, 507, 507, 1243, 1243, 516, 516, + 516, 516, 1220, 1221, 819, 875, 1034, 572, 547, 582, + 643, 522, 534, 587, 1243, 816, 948, 522, 945, 534, + 685, 985, 363, 330, 331, 818, 828, 627, 924, 1246, + 392, 1137, 579, 812, 418, 418, 418, 448, 523, 550, + 442, 443, 989, 1029, 824, 1136, 910, 1251, 1252, 451, + 600, 537, 1215, 1215, 1215, 682, 602, 604, 0, 622, + 0, 0, 640, 644, 940, 648, 656, 936, 0, 0, + 797, 0, 822, 1227, 1227, 1227, 1227, 929, 903, 903, + 901, 903, 681, 0, 270, 519, 519, 0, 0, 520, + 938, 933, 0, 827, 815, 984, 0, 0, 988, 0, + 1211, 0, 0, 0, 1139, 0, 0, 908, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 0, + 418, 0, 378, 379, 0, 0, 0, 630, 0, 631, + 898, 382, 383, 384, 0, 641, 987, 0, 385, 1213, + 1213, 987, 324, 1125, 884, 0, 0, 1126, 1129, 885, + 1130, 0, 1027, 831, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 270, 524, 524, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 950, - 950 + 0, 0, 0, 0, 0, 0, 943, 943 ); protected $gotoCheck = array( - 41, 41, 71, 6, 8, 64, 64, 105, 105, 105, + 41, 41, 71, 128, 111, 64, 64, 25, 128, 8, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 57, 57, 57, 57, 57, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, @@ -747,93 +742,90 @@ class Php7 extends \PhpParser\ParserAbstract 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 14, 107, 107, - 25, 22, 22, 22, 22, 107, 107, 107, 54, 54, - 19, 99, 99, 114, 74, 74, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 164, 164, 111, 88, - 14, 128, 14, 14, 14, 14, 128, 14, 14, 14, - 14, 14, 14, 24, 165, 165, 26, 164, 14, 48, - 24, 24, 24, 24, 24, 24, 74, 74, 14, 14, - 74, 164, 24, 24, 24, 165, 74, 74, 34, 19, - 44, 74, 74, 34, 151, 151, 34, 74, 63, 19, - 63, 152, 152, 11, 74, 74, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 71, 71, 71, 71, - 19, 19, 19, 71, 71, 74, 71, 71, 71, 5, - 71, 71, 71, 8, 8, 8, 8, 71, 71, 71, - 71, 71, 11, 74, 11, 154, 153, 153, 71, 71, - 71, 153, 153, 153, 153, 153, 153, 153, 153, 153, - 153, 18, 18, 18, 161, 71, 155, 155, 12, 71, - 12, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 163, 18, 18, 18, 18, 18, 23, 23, 23, - 23, 81, 81, 18, 18, 18, 47, 84, 84, 84, - 47, 47, 47, 94, 45, 47, 45, 8, 47, 47, - 47, 47, 47, 47, 8, 78, 78, 21, 7, 7, - 78, 7, 78, 60, 78, 78, 78, 80, 78, 7, - 7, 78, 7, 7, 80, 78, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 8, 8, 13, 158, - 158, 158, 8, 95, 8, 21, 62, 8, 135, 13, - 8, 98, 98, 98, 98, 160, 160, 76, 76, 103, - 98, 76, 76, 76, 76, 8, 8, 8, 22, 22, - 22, 8, 88, 88, 8, 8, 114, 114, 114, 82, - 82, 79, 82, 82, 13, 133, 133, 2, 2, 16, - 16, 17, 28, 15, 15, 15, 133, 16, 15, 38, - 8, 27, 36, 16, 114, 114, 114, 114, 15, 13, - 16, 101, 16, 16, 139, 90, 139, 113, 16, 144, - 141, 116, 139, -1, 40, 131, 114, 87, -1, -1, - 16, -1, 15, -1, -1, -1, -1, -1, 13, -1, - -1, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 21, 22, 15, 15, -1, -1, -1, 114, - -1, -1, 114, 114, 114, -1, -1, -1, -1, -1, + 41, 41, 41, 41, 41, 41, 41, 22, 22, 22, + 22, 14, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 26, 88, 74, 74, 99, 99, 114, 21, + 21, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 63, 11, 63, 14, 6, 14, 14, 14, 14, + 48, 14, 14, 14, 14, 14, 14, 23, 23, 23, + 23, 44, 14, 107, 107, 74, 74, 5, 74, 107, + 107, 107, 14, 14, 74, 74, 105, 105, 105, 74, + 74, 54, 54, 11, 74, 11, 165, 165, 152, 152, + 154, 74, 74, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 161, 165, 71, 71, 71, 71, 19, + 163, 74, 71, 71, 94, 71, 71, 71, 71, 71, + 71, 8, 8, 8, 8, 71, 139, 60, 139, 74, + 71, 71, 71, 71, 139, 21, 71, 71, 71, 13, + 133, 133, 7, 7, 82, 7, 82, 82, 95, 13, + 13, 133, 62, 7, 7, 71, 7, 7, 135, 71, + 158, 158, 158, 34, 13, 13, 19, 13, 34, 13, + 45, 34, 45, 18, 18, 18, 19, 28, 153, 153, + 13, 17, 13, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 18, 103, 19, 19, 19, 18, 18, + 18, 18, 27, 8, 18, 18, 18, 84, 84, 84, + 8, 155, 155, 151, 151, 13, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 164, 164, 98, 98, + 98, 98, 160, 160, 38, 16, 16, 98, 2, 2, + 13, 8, 8, 16, 164, 36, 101, 8, 16, 8, + 90, 113, 8, 88, 88, 16, 40, 16, 16, 164, + 12, 144, 12, 16, 22, 22, 22, 141, 13, 8, + 8, 8, 116, 131, 8, 16, 87, 8, 8, 80, + 81, 47, 114, 114, 114, 47, 47, 47, -1, 47, + -1, -1, 47, 47, 47, 47, 47, 47, -1, -1, + 24, -1, 8, 114, 114, 114, 114, 24, 24, 24, + 24, 24, 24, -1, 23, 23, 23, -1, -1, 24, + 24, 24, -1, 15, 15, 15, -1, -1, 15, -1, + 114, -1, -1, -1, 13, -1, -1, 15, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, -1, + 22, -1, 78, 78, -1, -1, -1, 78, -1, 78, + 15, 78, 78, 78, -1, 78, 114, -1, 78, 114, + 114, 114, 78, 76, 76, -1, -1, 76, 76, 76, + 76, -1, 15, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 23, 23, 23, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 98, - 98 + -1, -1, -1, -1, -1, -1, 98, 98 ); protected $gotoBase = array( - 0, 0, -232, 0, 0, 249, -6, 351, -16, 0, - 0, -37, -11, 79, -167, 22, 1, 148, 40, -188, - 0, 83, 158, 324, 199, 156, 202, 132, 162, 0, - 0, 0, 0, 0, -118, 0, 131, 0, 142, 0, - 66, -1, 0, 0, 211, -347, 0, -332, 192, 0, - 0, 0, 0, 0, 130, 0, 0, -23, 0, 0, - 323, 0, 161, 225, -229, 0, 0, 0, 0, 0, - 0, -5, 0, 0, -198, 0, 30, 42, -109, 157, - -77, -122, -246, 0, 53, 0, 0, 67, -267, 0, - 89, 0, 0, 0, 312, 352, 0, 0, 375, -63, - 0, 116, 0, 140, 0, -264, 0, -110, 0, 0, - 0, 186, 0, 118, 165, 0, 62, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -74, 0, - 0, 64, 0, 405, 0, 135, 0, 0, 0, -4, - 0, 63, 0, 0, 65, 0, 0, 0, 0, 0, - 0, -71, 7, 52, 258, 72, 0, 0, 99, 0, - 58, 276, 0, 292, -101, -83, 0, 0 + 0, 0, -276, 0, 0, 197, 186, 285, -11, 0, + 0, -87, 90, 9, -164, 53, -51, 39, 62, -100, + 0, -133, 154, 204, 446, 3, 168, 32, 48, 0, + 0, 0, 0, 0, -34, 0, 73, 0, 77, 0, + -2, -1, 0, 0, 192, -365, 0, -232, 183, 0, + 0, 0, 0, 0, 193, 0, 0, -23, 0, 0, + 237, 0, 67, 178, -229, 0, 0, 0, 0, 0, + 0, -6, 0, 0, -199, 0, 145, -173, 41, 0, + -19, -21, -376, 0, 70, 0, 0, 16, -280, 0, + 23, 0, 0, 0, 233, 257, 0, 0, 352, -58, + 0, 50, 0, 75, 0, -45, 0, -55, 0, 0, + 0, 2, 0, 51, 171, 0, 13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -262, 0, + 0, 12, 0, 260, 0, 45, 0, 0, 0, -189, + 0, 10, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 58, 4, 94, 213, 127, 0, 0, 27, 0, + 34, 225, 0, 231, 86, -54, 0, 0 ); protected $gotoDefault = array( - -32768, 485, 695, 4, 696, 769, 777, 569, 503, 664, - 324, 596, 390, 331, 862, 1040, 551, 796, 1160, 1168, - 428, 799, 312, 326, 844, 845, 846, 366, 351, 357, - 364, 617, 597, 467, 831, 422, 823, 459, 826, 421, - 835, 158, 386, 483, 839, 3, 841, 530, 872, 352, - 849, 353, 641, 851, 536, 853, 854, 360, 367, 368, - 1045, 544, 593, 866, 237, 538, 867, 350, 868, 875, - 355, 358, 650, 438, 478, 380, 1021, 579, 614, 416, - 447, 591, 603, 589, 902, 460, 436, 916, 327, 924, - 693, 1052, 609, 462, 932, 610, 939, 942, 504, 505, - 452, 954, 268, 463, 981, 633, 634, 966, 612, 979, - 446, 985, 423, 993, 1204, 426, 997, 260, 1000, 269, - 385, 401, 1005, 1006, 7, 1011, 656, 657, 10, 265, - 482, 1035, 651, 420, 1051, 406, 1120, 1122, 532, 464, - 1140, 1139, 644, 479, 1145, 1207, 417, 506, 448, 299, - 507, 287, 315, 296, 522, 278, 316, 508, 449, 1213, - 1221, 313, 29, 1241, 1252, 322, 548, 584 + -32768, 482, 689, 4, 690, 763, 771, 566, 498, 659, + 325, 592, 390, 1209, 856, 1033, 548, 790, 1153, 1161, + 427, 793, 313, 327, 838, 839, 840, 367, 352, 358, + 365, 613, 593, 464, 825, 421, 817, 456, 820, 420, + 829, 158, 387, 480, 833, 3, 835, 525, 866, 353, + 843, 354, 636, 845, 533, 847, 848, 361, 368, 369, + 1038, 541, 589, 860, 237, 535, 861, 351, 862, 869, + 356, 359, 645, 436, 475, 381, 1014, 576, 610, 432, + 450, 599, 598, 586, 895, 457, 434, 909, 328, 917, + 687, 1045, 605, 459, 925, 606, 932, 935, 499, 500, + 449, 947, 268, 460, 974, 628, 629, 959, 608, 972, + 444, 978, 422, 986, 1197, 425, 990, 260, 993, 269, + 386, 401, 998, 999, 8, 1004, 651, 652, 10, 265, + 479, 1028, 646, 419, 1044, 406, 1113, 1115, 527, 461, + 1133, 1132, 639, 476, 1138, 1200, 416, 501, 445, 299, + 502, 290, 316, 296, 517, 277, 317, 503, 446, 1206, + 1214, 314, 29, 1234, 1245, 323, 545, 581 ); protected $ruleToNonTerminal = array( @@ -857,22 +849,22 @@ class Php7 extends \PhpParser\ParserAbstract 48, 48, 48, 48, 48, 48, 48, 48, 24, 24, 67, 67, 70, 70, 69, 68, 68, 61, 73, 73, 74, 74, 75, 75, 76, 76, 25, 25, 26, 26, - 26, 26, 79, 79, 79, 80, 80, 83, 83, 81, - 81, 84, 85, 85, 55, 55, 63, 63, 66, 66, - 66, 65, 86, 86, 87, 56, 56, 56, 56, 88, - 88, 89, 89, 90, 90, 91, 92, 92, 93, 93, - 94, 94, 53, 53, 49, 49, 96, 51, 51, 97, - 50, 50, 52, 52, 62, 62, 62, 62, 77, 77, - 100, 100, 102, 102, 102, 102, 101, 101, 101, 104, - 104, 104, 105, 105, 107, 107, 107, 106, 106, 108, - 108, 109, 109, 109, 103, 103, 78, 78, 78, 19, - 19, 110, 110, 111, 111, 111, 111, 58, 112, 112, - 113, 59, 115, 115, 116, 116, 117, 117, 82, 118, - 118, 118, 118, 118, 123, 123, 124, 124, 125, 125, - 125, 125, 125, 126, 127, 127, 122, 122, 119, 119, - 121, 121, 129, 129, 128, 128, 128, 128, 128, 128, - 120, 130, 130, 132, 131, 131, 60, 95, 133, 133, - 54, 54, 41, 41, 41, 41, 41, 41, 41, 41, + 26, 79, 79, 79, 80, 80, 83, 83, 81, 81, + 84, 85, 85, 55, 55, 63, 63, 66, 66, 66, + 65, 86, 86, 87, 56, 56, 56, 56, 88, 88, + 89, 89, 90, 90, 91, 92, 92, 93, 93, 94, + 94, 53, 53, 49, 49, 96, 51, 51, 97, 50, + 50, 52, 52, 62, 62, 62, 62, 77, 77, 100, + 100, 102, 102, 102, 102, 101, 101, 101, 104, 104, + 104, 105, 105, 107, 107, 107, 106, 106, 108, 108, + 109, 109, 109, 103, 103, 78, 78, 78, 19, 19, + 110, 110, 111, 111, 111, 111, 58, 112, 112, 113, + 59, 115, 115, 116, 116, 117, 117, 82, 118, 118, + 118, 118, 118, 123, 123, 124, 124, 125, 125, 125, + 125, 125, 126, 127, 127, 122, 122, 119, 119, 121, + 121, 129, 129, 128, 128, 128, 128, 128, 128, 120, + 130, 130, 132, 131, 131, 60, 95, 133, 133, 54, + 54, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, @@ -881,20 +873,20 @@ class Php7 extends \PhpParser\ParserAbstract 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 140, 134, 134, 139, 139, 142, - 143, 143, 144, 145, 145, 145, 18, 18, 71, 71, - 71, 71, 135, 135, 135, 135, 147, 147, 136, 136, - 138, 138, 138, 141, 141, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 153, 153, 99, 155, 155, 155, - 155, 137, 137, 137, 137, 137, 137, 137, 137, 57, - 57, 150, 150, 150, 150, 156, 156, 146, 146, 146, - 157, 157, 157, 157, 157, 157, 72, 72, 64, 64, - 64, 64, 114, 114, 114, 114, 160, 159, 149, 149, - 149, 149, 149, 149, 149, 148, 148, 148, 158, 158, - 158, 158, 98, 154, 162, 162, 161, 161, 163, 163, - 163, 163, 163, 163, 163, 163, 151, 151, 151, 151, - 165, 166, 164, 164, 164, 164, 164, 164, 164, 164, - 167, 167, 167, 167 + 41, 41, 41, 140, 134, 134, 139, 139, 142, 143, + 143, 144, 145, 145, 145, 18, 18, 71, 71, 71, + 71, 135, 135, 135, 135, 147, 147, 136, 136, 138, + 138, 138, 141, 141, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 153, 153, 99, 155, 155, 155, 155, + 137, 137, 137, 137, 137, 137, 137, 137, 57, 57, + 150, 150, 150, 150, 156, 156, 146, 146, 146, 157, + 157, 157, 157, 157, 157, 72, 72, 64, 64, 64, + 64, 114, 114, 114, 114, 160, 159, 149, 149, 149, + 149, 149, 149, 149, 148, 148, 148, 158, 158, 158, + 158, 98, 154, 162, 162, 161, 161, 163, 163, 163, + 163, 163, 163, 163, 163, 151, 151, 151, 151, 165, + 166, 164, 164, 164, 164, 164, 164, 164, 164, 167, + 167, 167, 167 ); protected $ruleToLength = array( @@ -917,45 +909,45 @@ class Php7 extends \PhpParser\ParserAbstract 5, 3, 3, 3, 3, 3, 3, 1, 2, 5, 7, 9, 6, 5, 6, 3, 2, 1, 1, 1, 0, 2, 1, 3, 8, 0, 4, 2, 1, 3, - 0, 1, 0, 1, 3, 1, 8, 9, 7, 8, - 7, 6, 1, 2, 2, 0, 2, 0, 2, 0, - 2, 2, 1, 3, 1, 4, 1, 4, 1, 1, - 4, 2, 1, 3, 3, 3, 4, 4, 5, 0, - 2, 4, 3, 1, 1, 7, 0, 2, 1, 3, - 3, 4, 1, 4, 0, 2, 5, 0, 2, 6, - 0, 2, 0, 3, 1, 2, 1, 1, 2, 0, - 1, 3, 0, 1, 1, 1, 6, 8, 6, 1, - 2, 1, 1, 1, 1, 1, 1, 3, 3, 3, - 3, 1, 2, 1, 0, 1, 0, 2, 2, 2, - 4, 1, 3, 1, 2, 2, 3, 2, 3, 1, - 1, 2, 3, 1, 1, 3, 2, 0, 1, 5, - 5, 10, 3, 1, 1, 3, 0, 2, 4, 5, - 4, 4, 4, 3, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, - 2, 1, 3, 1, 1, 3, 2, 2, 3, 1, - 0, 1, 1, 3, 3, 3, 4, 1, 1, 2, + 0, 1, 0, 1, 3, 1, 8, 9, 8, 7, + 6, 1, 2, 2, 0, 2, 0, 2, 0, 2, + 2, 1, 3, 1, 4, 1, 4, 1, 1, 4, + 2, 1, 3, 3, 3, 4, 4, 5, 0, 2, + 4, 3, 1, 1, 7, 0, 2, 1, 3, 3, + 4, 1, 4, 0, 2, 5, 0, 2, 6, 0, + 2, 0, 3, 1, 2, 1, 1, 2, 0, 1, + 3, 0, 1, 1, 1, 6, 8, 6, 1, 2, + 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, + 1, 2, 1, 0, 1, 0, 2, 2, 2, 4, + 1, 3, 1, 2, 2, 3, 2, 3, 1, 1, + 2, 3, 1, 1, 3, 2, 0, 1, 5, 5, + 10, 3, 1, 1, 3, 0, 2, 4, 5, 4, + 4, 4, 3, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, + 1, 3, 1, 1, 3, 2, 2, 3, 1, 0, + 1, 1, 3, 3, 3, 4, 1, 1, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, - 4, 3, 4, 4, 2, 2, 4, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, - 2, 1, 2, 4, 2, 2, 8, 9, 8, 9, - 9, 10, 9, 10, 8, 3, 2, 0, 4, 2, - 1, 3, 2, 2, 2, 4, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 1, 1, 0, 3, - 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 3, 4, 1, 1, - 3, 1, 1, 1, 1, 1, 3, 2, 3, 0, - 1, 1, 3, 1, 1, 1, 1, 1, 3, 1, - 1, 4, 4, 1, 4, 4, 0, 1, 1, 1, - 3, 3, 1, 4, 2, 2, 1, 3, 1, 4, - 4, 3, 3, 3, 3, 1, 3, 1, 1, 3, - 1, 1, 4, 1, 1, 1, 3, 1, 1, 2, - 1, 3, 4, 3, 2, 0, 2, 2, 1, 2, - 1, 1, 1, 4, 3, 3, 3, 3, 6, 3, - 1, 1, 2, 1 + 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, + 3, 4, 4, 2, 2, 4, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 1, 3, 2, + 1, 2, 4, 2, 2, 8, 9, 8, 9, 9, + 10, 9, 10, 8, 3, 2, 0, 4, 2, 1, + 3, 2, 2, 2, 4, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 1, 0, 3, 0, + 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 3, 3, 4, 1, 1, 3, + 1, 1, 1, 1, 1, 3, 2, 3, 0, 1, + 1, 3, 1, 1, 1, 1, 1, 3, 1, 1, + 4, 4, 1, 4, 4, 0, 1, 1, 1, 3, + 3, 1, 4, 2, 2, 1, 3, 1, 4, 4, + 3, 3, 3, 3, 1, 3, 1, 1, 3, 1, + 1, 4, 1, 1, 1, 3, 1, 1, 2, 1, + 3, 4, 3, 2, 0, 2, 2, 1, 2, 1, + 1, 1, 4, 3, 3, 3, 3, 6, 3, 1, + 1, 2, 1 ); protected function initReduceCallbacks() { @@ -1580,478 +1572,477 @@ class Php7 extends \PhpParser\ParserAbstract $this->semValue = new Stmt\Function_($this->semStack[$stackPos-(9-4)], ['byRef' => $this->semStack[$stackPos-(9-3)], 'params' => $this->semStack[$stackPos-(9-6)], 'returnType' => $this->semStack[$stackPos-(9-8)], 'stmts' => $this->semStack[$stackPos-(9-9)], 'attrGroups' => $this->semStack[$stackPos-(9-1)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); }, 198 => function ($stackPos) { - $this->semValue = new Stmt\Class_($this->semStack[$stackPos-(7-2)], ['type' => $this->semStack[$stackPos-(7-1)], 'extends' => $this->semStack[$stackPos-(7-3)], 'implements' => $this->semStack[$stackPos-(7-4)], 'stmts' => $this->semStack[$stackPos-(7-6)], 'attrGroups' => []], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); - $this->checkClass($this->semValue, $stackPos-(7-2)); - }, - 199 => function ($stackPos) { $this->semValue = new Stmt\Class_($this->semStack[$stackPos-(8-3)], ['type' => $this->semStack[$stackPos-(8-2)], 'extends' => $this->semStack[$stackPos-(8-4)], 'implements' => $this->semStack[$stackPos-(8-5)], 'stmts' => $this->semStack[$stackPos-(8-7)], 'attrGroups' => $this->semStack[$stackPos-(8-1)]], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); $this->checkClass($this->semValue, $stackPos-(8-3)); }, - 200 => function ($stackPos) { + 199 => function ($stackPos) { $this->semValue = new Stmt\Interface_($this->semStack[$stackPos-(7-3)], ['extends' => $this->semStack[$stackPos-(7-4)], 'stmts' => $this->semStack[$stackPos-(7-6)], 'attrGroups' => $this->semStack[$stackPos-(7-1)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); $this->checkInterface($this->semValue, $stackPos-(7-3)); }, - 201 => function ($stackPos) { + 200 => function ($stackPos) { $this->semValue = new Stmt\Trait_($this->semStack[$stackPos-(6-3)], ['stmts' => $this->semStack[$stackPos-(6-5)], 'attrGroups' => $this->semStack[$stackPos-(6-1)]], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); }, - 202 => function ($stackPos) { + 201 => function ($stackPos) { $this->semValue = 0; }, - 203 => function ($stackPos) { + 202 => function ($stackPos) { $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; }, - 204 => function ($stackPos) { + 203 => function ($stackPos) { $this->semValue = Stmt\Class_::MODIFIER_FINAL; }, - 205 => function ($stackPos) { + 204 => function ($stackPos) { $this->semValue = null; }, + 205 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, 206 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(2-2)]; + $this->semValue = array(); }, 207 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = $this->semStack[$stackPos-(2-2)]; }, 208 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(2-2)]; + $this->semValue = array(); }, 209 => function ($stackPos) { - $this->semValue = array(); - }, - 210 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-2)]; }, - 211 => function ($stackPos) { + 210 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-1)]; }, + 211 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, 212 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos-(1-1)]); + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; }, 213 => function ($stackPos) { - $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); }, 214 => function ($stackPos) { - $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + $this->semValue = $this->semStack[$stackPos-(4-2)]; }, 215 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(4-2)]; + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); }, 216 => function ($stackPos) { - $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + $this->semValue = $this->semStack[$stackPos-(4-2)]; }, 217 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(4-2)]; - }, - 218 => function ($stackPos) { $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); }, - 219 => function ($stackPos) { + 218 => function ($stackPos) { $this->semValue = null; }, - 220 => function ($stackPos) { + 219 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(4-2)]; }, - 221 => function ($stackPos) { + 220 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-1)]; }, - 222 => function ($stackPos) { + 221 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)]); }, - 223 => function ($stackPos) { + 222 => function ($stackPos) { $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; }, - 224 => function ($stackPos) { + 223 => function ($stackPos) { $this->semValue = new Stmt\DeclareDeclare($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 225 => function ($stackPos) { + 224 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(3-2)]; }, - 226 => function ($stackPos) { + 225 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(4-3)]; }, - 227 => function ($stackPos) { + 226 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(4-2)]; }, - 228 => function ($stackPos) { + 227 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(5-3)]; }, - 229 => function ($stackPos) { + 228 => function ($stackPos) { $this->semValue = array(); }, - 230 => function ($stackPos) { + 229 => function ($stackPos) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }, - 231 => function ($stackPos) { + 230 => function ($stackPos) { $this->semValue = new Stmt\Case_($this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 232 => function ($stackPos) { + 231 => function ($stackPos) { $this->semValue = new Stmt\Case_(null, $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, + 232 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, 233 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos]; }, 234 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, - 235 => function ($stackPos) { $this->semValue = new Expr\Match_($this->semStack[$stackPos-(7-3)], $this->semStack[$stackPos-(7-6)], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); }, - 236 => function ($stackPos) { + 235 => function ($stackPos) { $this->semValue = []; }, - 237 => function ($stackPos) { + 236 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-1)]; }, - 238 => function ($stackPos) { + 237 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)]); }, - 239 => function ($stackPos) { + 238 => function ($stackPos) { $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; }, - 240 => function ($stackPos) { + 239 => function ($stackPos) { $this->semValue = new Node\MatchArm($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 241 => function ($stackPos) { + 240 => function ($stackPos) { $this->semValue = new Node\MatchArm(null, $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 242 => function ($stackPos) { + 241 => function ($stackPos) { $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); }, - 243 => function ($stackPos) { + 242 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(4-2)]; }, - 244 => function ($stackPos) { + 243 => function ($stackPos) { $this->semValue = array(); }, + 244 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, 245 => function ($stackPos) { - $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; - }, - 246 => function ($stackPos) { $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(5-3)], is_array($this->semStack[$stackPos-(5-5)]) ? $this->semStack[$stackPos-(5-5)] : array($this->semStack[$stackPos-(5-5)]), $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); }, - 247 => function ($stackPos) { + 246 => function ($stackPos) { $this->semValue = array(); }, - 248 => function ($stackPos) { + 247 => function ($stackPos) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }, - 249 => function ($stackPos) { + 248 => function ($stackPos) { $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); }, - 250 => function ($stackPos) { + 249 => function ($stackPos) { $this->semValue = null; }, - 251 => function ($stackPos) { + 250 => function ($stackPos) { $this->semValue = new Stmt\Else_(is_array($this->semStack[$stackPos-(2-2)]) ? $this->semStack[$stackPos-(2-2)] : array($this->semStack[$stackPos-(2-2)]), $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 252 => function ($stackPos) { + 251 => function ($stackPos) { $this->semValue = null; }, - 253 => function ($stackPos) { + 252 => function ($stackPos) { $this->semValue = new Stmt\Else_($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 254 => function ($stackPos) { + 253 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)], false); }, - 255 => function ($stackPos) { + 254 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(2-2)], true); }, + 255 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)], false); + }, 256 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)], false); }, 257 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos-(1-1)], false); - }, - 258 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-1)]; }, - 259 => function ($stackPos) { + 258 => function ($stackPos) { $this->semValue = array(); }, - 260 => function ($stackPos) { + 259 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)]); }, - 261 => function ($stackPos) { + 260 => function ($stackPos) { $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; }, - 262 => function ($stackPos) { + 261 => function ($stackPos) { $this->semValue = 0; }, - 263 => function ($stackPos) { + 262 => function ($stackPos) { $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; }, - 264 => function ($stackPos) { + 263 => function ($stackPos) { $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; }, - 265 => function ($stackPos) { + 264 => function ($stackPos) { $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; }, - 266 => function ($stackPos) { + 265 => function ($stackPos) { $this->semValue = new Node\Param($this->semStack[$stackPos-(6-6)], null, $this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-4)], $this->semStack[$stackPos-(6-5)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes, $this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-1)]); $this->checkParam($this->semValue); }, - 267 => function ($stackPos) { + 266 => function ($stackPos) { $this->semValue = new Node\Param($this->semStack[$stackPos-(8-6)], $this->semStack[$stackPos-(8-8)], $this->semStack[$stackPos-(8-3)], $this->semStack[$stackPos-(8-4)], $this->semStack[$stackPos-(8-5)], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes, $this->semStack[$stackPos-(8-2)], $this->semStack[$stackPos-(8-1)]); $this->checkParam($this->semValue); }, - 268 => function ($stackPos) { + 267 => function ($stackPos) { $this->semValue = new Node\Param(new Expr\Error($this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes), null, $this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-4)], $this->semStack[$stackPos-(6-5)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes, $this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-1)]); }, - 269 => function ($stackPos) { + 268 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, + 269 => function ($stackPos) { + $this->semValue = new Node\NullableType($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, 270 => function ($stackPos) { - $this->semValue = new Node\NullableType($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + $this->semValue = new Node\UnionType($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, 271 => function ($stackPos) { - $this->semValue = new Node\UnionType($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 272 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; - }, - 273 => function ($stackPos) { $this->semValue = new Node\Name('static', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 274 => function ($stackPos) { + 273 => function ($stackPos) { $this->semValue = $this->handleBuiltinTypes($this->semStack[$stackPos-(1-1)]); }, - 275 => function ($stackPos) { + 274 => function ($stackPos) { $this->semValue = new Node\Identifier('array', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 276 => function ($stackPos) { + 275 => function ($stackPos) { $this->semValue = new Node\Identifier('callable', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 277 => function ($stackPos) { + 276 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)]); }, + 277 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, 278 => function ($stackPos) { - $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; - }, - 279 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)]); }, - 280 => function ($stackPos) { + 279 => function ($stackPos) { $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; }, + 280 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, 281 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; - }, - 282 => function ($stackPos) { $this->semValue = new Node\NullableType($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 283 => function ($stackPos) { + 282 => function ($stackPos) { $this->semValue = new Node\UnionType($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 284 => function ($stackPos) { + 283 => function ($stackPos) { $this->semValue = null; }, - 285 => function ($stackPos) { + 284 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, - 286 => function ($stackPos) { + 285 => function ($stackPos) { $this->semValue = null; }, - 287 => function ($stackPos) { + 286 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-2)]; }, - 288 => function ($stackPos) { + 287 => function ($stackPos) { $this->semValue = null; }, - 289 => function ($stackPos) { + 288 => function ($stackPos) { $this->semValue = array(); }, - 290 => function ($stackPos) { + 289 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(4-2)]; }, - 291 => function ($stackPos) { + 290 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)]); }, + 291 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, 292 => function ($stackPos) { - $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; - }, - 293 => function ($stackPos) { $this->semValue = new Node\Arg($this->semStack[$stackPos-(1-1)], false, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 294 => function ($stackPos) { + 293 => function ($stackPos) { $this->semValue = new Node\Arg($this->semStack[$stackPos-(2-2)], true, false, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 295 => function ($stackPos) { + 294 => function ($stackPos) { $this->semValue = new Node\Arg($this->semStack[$stackPos-(2-2)], false, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 296 => function ($stackPos) { + 295 => function ($stackPos) { $this->semValue = new Node\Arg($this->semStack[$stackPos-(3-3)], false, false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes, $this->semStack[$stackPos-(3-1)]); }, - 297 => function ($stackPos) { + 296 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-1)]; }, + 297 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, 298 => function ($stackPos) { - $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + $this->semValue = array($this->semStack[$stackPos-(1-1)]); }, 299 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos-(1-1)]); + $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 300 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); - }, - 301 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-1)]; }, - 302 => function ($stackPos) { + 301 => function ($stackPos) { $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; }, - 303 => function ($stackPos) { + 302 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)]); }, - 304 => function ($stackPos) { + 303 => function ($stackPos) { $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(1-1)], null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 305 => function ($stackPos) { + 304 => function ($stackPos) { $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 306 => function ($stackPos) { + 305 => function ($stackPos) { if ($this->semStack[$stackPos-(2-2)] !== null) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; } }, - 307 => function ($stackPos) { + 306 => function ($stackPos) { $this->semValue = array(); }, - 308 => function ($stackPos) { + 307 => function ($stackPos) { $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments'])); } else { $nop = null; }; if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; }, - 309 => function ($stackPos) { + 308 => function ($stackPos) { $this->semValue = new Stmt\Property($this->semStack[$stackPos-(5-2)], $this->semStack[$stackPos-(5-4)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes, $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-1)]); $this->checkProperty($this->semValue, $stackPos-(5-2)); }, - 310 => function ($stackPos) { + 309 => function ($stackPos) { $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos-(5-4)], $this->semStack[$stackPos-(5-2)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes, $this->semStack[$stackPos-(5-1)]); $this->checkClassConst($this->semValue, $stackPos-(5-2)); }, - 311 => function ($stackPos) { + 310 => function ($stackPos) { $this->semValue = new Stmt\ClassMethod($this->semStack[$stackPos-(10-5)], ['type' => $this->semStack[$stackPos-(10-2)], 'byRef' => $this->semStack[$stackPos-(10-4)], 'params' => $this->semStack[$stackPos-(10-7)], 'returnType' => $this->semStack[$stackPos-(10-9)], 'stmts' => $this->semStack[$stackPos-(10-10)], 'attrGroups' => $this->semStack[$stackPos-(10-1)]], $this->startAttributeStack[$stackPos-(10-1)] + $this->endAttributes); $this->checkClassMethod($this->semValue, $stackPos-(10-2)); }, - 312 => function ($stackPos) { + 311 => function ($stackPos) { $this->semValue = new Stmt\TraitUse($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 313 => function ($stackPos) { + 312 => function ($stackPos) { $this->semValue = null; /* will be skipped */ }, - 314 => function ($stackPos) { + 313 => function ($stackPos) { $this->semValue = array(); }, - 315 => function ($stackPos) { + 314 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(3-2)]; }, - 316 => function ($stackPos) { + 315 => function ($stackPos) { $this->semValue = array(); }, - 317 => function ($stackPos) { + 316 => function ($stackPos) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }, - 318 => function ($stackPos) { + 317 => function ($stackPos) { $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 319 => function ($stackPos) { + 318 => function ($stackPos) { $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(5-1)][0], $this->semStack[$stackPos-(5-1)][1], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-4)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); }, - 320 => function ($stackPos) { + 319 => function ($stackPos) { $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], $this->semStack[$stackPos-(4-3)], null, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, + 320 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, 321 => function ($stackPos) { $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, 322 => function ($stackPos) { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); - }, - 323 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)]); }, - 324 => function ($stackPos) { + 323 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, - 325 => function ($stackPos) { + 324 => function ($stackPos) { $this->semValue = array(null, $this->semStack[$stackPos-(1-1)]); }, - 326 => function ($stackPos) { + 325 => function ($stackPos) { $this->semValue = null; }, + 326 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, 327 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 328 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; + $this->semValue = 0; }, 329 => function ($stackPos) { $this->semValue = 0; }, 330 => function ($stackPos) { - $this->semValue = 0; + $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 331 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 332 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; - }, - 333 => function ($stackPos) { $this->checkModifier($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $this->semValue = $this->semStack[$stackPos-(2-1)] | $this->semStack[$stackPos-(2-2)]; }, - 334 => function ($stackPos) { + 333 => function ($stackPos) { $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; }, - 335 => function ($stackPos) { + 334 => function ($stackPos) { $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; }, - 336 => function ($stackPos) { + 335 => function ($stackPos) { $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; }, - 337 => function ($stackPos) { + 336 => function ($stackPos) { $this->semValue = Stmt\Class_::MODIFIER_STATIC; }, - 338 => function ($stackPos) { + 337 => function ($stackPos) { $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; }, - 339 => function ($stackPos) { + 338 => function ($stackPos) { $this->semValue = Stmt\Class_::MODIFIER_FINAL; }, - 340 => function ($stackPos) { + 339 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-1)]; }, - 341 => function ($stackPos) { + 340 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)]); }, - 342 => function ($stackPos) { + 341 => function ($stackPos) { $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; }, - 343 => function ($stackPos) { + 342 => function ($stackPos) { $this->semValue = new Node\VarLikeIdentifier(substr($this->semStack[$stackPos-(1-1)], 1), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 344 => function ($stackPos) { + 343 => function ($stackPos) { $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos-(1-1)], null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 345 => function ($stackPos) { + 344 => function ($stackPos) { $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, + 345 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, 346 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-1)]; }, 347 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(2-1)]; - }, - 348 => function ($stackPos) { $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; }, - 349 => function ($stackPos) { + 348 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)]); }, - 350 => function ($stackPos) { + 349 => function ($stackPos) { $this->semValue = array(); }, + 350 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, 351 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 352 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; + $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, 353 => function ($stackPos) { $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); @@ -2060,428 +2051,428 @@ class Php7 extends \PhpParser\ParserAbstract $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, 355 => function ($stackPos) { - $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + $this->semValue = new Expr\AssignRef($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, 356 => function ($stackPos) { - $this->semValue = new Expr\AssignRef($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 357 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 358 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; - }, - 359 => function ($stackPos) { $this->semValue = new Expr\Clone_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 360 => function ($stackPos) { + 359 => function ($stackPos) { $this->semValue = new Expr\AssignOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 361 => function ($stackPos) { + 360 => function ($stackPos) { $this->semValue = new Expr\AssignOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 362 => function ($stackPos) { + 361 => function ($stackPos) { $this->semValue = new Expr\AssignOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 363 => function ($stackPos) { + 362 => function ($stackPos) { $this->semValue = new Expr\AssignOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 364 => function ($stackPos) { + 363 => function ($stackPos) { $this->semValue = new Expr\AssignOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 365 => function ($stackPos) { + 364 => function ($stackPos) { $this->semValue = new Expr\AssignOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 366 => function ($stackPos) { + 365 => function ($stackPos) { $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 367 => function ($stackPos) { + 366 => function ($stackPos) { $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 368 => function ($stackPos) { + 367 => function ($stackPos) { $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 369 => function ($stackPos) { + 368 => function ($stackPos) { $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 370 => function ($stackPos) { + 369 => function ($stackPos) { $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 371 => function ($stackPos) { + 370 => function ($stackPos) { $this->semValue = new Expr\AssignOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 372 => function ($stackPos) { + 371 => function ($stackPos) { $this->semValue = new Expr\AssignOp\Coalesce($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 373 => function ($stackPos) { + 372 => function ($stackPos) { $this->semValue = new Expr\PostInc($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 374 => function ($stackPos) { + 373 => function ($stackPos) { $this->semValue = new Expr\PreInc($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 375 => function ($stackPos) { + 374 => function ($stackPos) { $this->semValue = new Expr\PostDec($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 376 => function ($stackPos) { + 375 => function ($stackPos) { $this->semValue = new Expr\PreDec($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 377 => function ($stackPos) { + 376 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 378 => function ($stackPos) { + 377 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 379 => function ($stackPos) { + 378 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 380 => function ($stackPos) { + 379 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 381 => function ($stackPos) { + 380 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 382 => function ($stackPos) { + 381 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 383 => function ($stackPos) { + 382 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 384 => function ($stackPos) { + 383 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 385 => function ($stackPos) { + 384 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 386 => function ($stackPos) { + 385 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 387 => function ($stackPos) { + 386 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 388 => function ($stackPos) { + 387 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 389 => function ($stackPos) { + 388 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 390 => function ($stackPos) { + 389 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 391 => function ($stackPos) { + 390 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 392 => function ($stackPos) { + 391 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 393 => function ($stackPos) { + 392 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 394 => function ($stackPos) { + 393 => function ($stackPos) { $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 395 => function ($stackPos) { + 394 => function ($stackPos) { $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 396 => function ($stackPos) { + 395 => function ($stackPos) { $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 397 => function ($stackPos) { + 396 => function ($stackPos) { $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 398 => function ($stackPos) { + 397 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 399 => function ($stackPos) { + 398 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 400 => function ($stackPos) { + 399 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 401 => function ($stackPos) { + 400 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 402 => function ($stackPos) { + 401 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 403 => function ($stackPos) { + 402 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 404 => function ($stackPos) { + 403 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 405 => function ($stackPos) { + 404 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 406 => function ($stackPos) { + 405 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 407 => function ($stackPos) { + 406 => function ($stackPos) { $this->semValue = new Expr\Instanceof_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 408 => function ($stackPos) { + 407 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(3-2)]; }, - 409 => function ($stackPos) { + 408 => function ($stackPos) { $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(5-1)], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); }, - 410 => function ($stackPos) { + 409 => function ($stackPos) { $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(4-1)], null, $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 411 => function ($stackPos) { + 410 => function ($stackPos) { $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 412 => function ($stackPos) { + 411 => function ($stackPos) { $this->semValue = new Expr\Isset_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 413 => function ($stackPos) { + 412 => function ($stackPos) { $this->semValue = new Expr\Empty_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 414 => function ($stackPos) { + 413 => function ($stackPos) { $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 415 => function ($stackPos) { + 414 => function ($stackPos) { $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 416 => function ($stackPos) { + 415 => function ($stackPos) { $this->semValue = new Expr\Eval_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 417 => function ($stackPos) { + 416 => function ($stackPos) { $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 418 => function ($stackPos) { + 417 => function ($stackPos) { $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 419 => function ($stackPos) { + 418 => function ($stackPos) { $this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 420 => function ($stackPos) { + 419 => function ($stackPos) { $attrs = $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = $this->getFloatCastKind($this->semStack[$stackPos-(2-1)]); $this->semValue = new Expr\Cast\Double($this->semStack[$stackPos-(2-2)], $attrs); }, - 421 => function ($stackPos) { + 420 => function ($stackPos) { $this->semValue = new Expr\Cast\String_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 422 => function ($stackPos) { + 421 => function ($stackPos) { $this->semValue = new Expr\Cast\Array_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 423 => function ($stackPos) { + 422 => function ($stackPos) { $this->semValue = new Expr\Cast\Object_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 424 => function ($stackPos) { + 423 => function ($stackPos) { $this->semValue = new Expr\Cast\Bool_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 425 => function ($stackPos) { + 424 => function ($stackPos) { $this->semValue = new Expr\Cast\Unset_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 426 => function ($stackPos) { + 425 => function ($stackPos) { $attrs = $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = strtolower($this->semStack[$stackPos-(2-1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; $this->semValue = new Expr\Exit_($this->semStack[$stackPos-(2-2)], $attrs); }, - 427 => function ($stackPos) { + 426 => function ($stackPos) { $this->semValue = new Expr\ErrorSuppress($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 428 => function ($stackPos) { + 427 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, - 429 => function ($stackPos) { + 428 => function ($stackPos) { $this->semValue = new Expr\ShellExec($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 430 => function ($stackPos) { + 429 => function ($stackPos) { $this->semValue = new Expr\Print_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 431 => function ($stackPos) { + 430 => function ($stackPos) { $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 432 => function ($stackPos) { + 431 => function ($stackPos) { $this->semValue = new Expr\Yield_($this->semStack[$stackPos-(2-2)], null, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 433 => function ($stackPos) { + 432 => function ($stackPos) { $this->semValue = new Expr\Yield_($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-2)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 434 => function ($stackPos) { + 433 => function ($stackPos) { $this->semValue = new Expr\YieldFrom($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 435 => function ($stackPos) { + 434 => function ($stackPos) { $this->semValue = new Expr\Throw_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 436 => function ($stackPos) { + 435 => function ($stackPos) { $this->semValue = new Expr\ArrowFunction(['static' => false, 'byRef' => $this->semStack[$stackPos-(8-2)], 'params' => $this->semStack[$stackPos-(8-4)], 'returnType' => $this->semStack[$stackPos-(8-6)], 'expr' => $this->semStack[$stackPos-(8-8)], 'attrGroups' => []], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); }, - 437 => function ($stackPos) { + 436 => function ($stackPos) { $this->semValue = new Expr\ArrowFunction(['static' => true, 'byRef' => $this->semStack[$stackPos-(9-3)], 'params' => $this->semStack[$stackPos-(9-5)], 'returnType' => $this->semStack[$stackPos-(9-7)], 'expr' => $this->semStack[$stackPos-(9-9)], 'attrGroups' => []], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); }, - 438 => function ($stackPos) { + 437 => function ($stackPos) { $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$stackPos-(8-2)], 'params' => $this->semStack[$stackPos-(8-4)], 'uses' => $this->semStack[$stackPos-(8-6)], 'returnType' => $this->semStack[$stackPos-(8-7)], 'stmts' => $this->semStack[$stackPos-(8-8)], 'attrGroups' => []], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); }, - 439 => function ($stackPos) { + 438 => function ($stackPos) { $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$stackPos-(9-3)], 'params' => $this->semStack[$stackPos-(9-5)], 'uses' => $this->semStack[$stackPos-(9-7)], 'returnType' => $this->semStack[$stackPos-(9-8)], 'stmts' => $this->semStack[$stackPos-(9-9)], 'attrGroups' => []], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); }, - 440 => function ($stackPos) { + 439 => function ($stackPos) { $this->semValue = new Expr\ArrowFunction(['static' => false, 'byRef' => $this->semStack[$stackPos-(9-3)], 'params' => $this->semStack[$stackPos-(9-5)], 'returnType' => $this->semStack[$stackPos-(9-7)], 'expr' => $this->semStack[$stackPos-(9-9)], 'attrGroups' => $this->semStack[$stackPos-(9-1)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); }, - 441 => function ($stackPos) { + 440 => function ($stackPos) { $this->semValue = new Expr\ArrowFunction(['static' => true, 'byRef' => $this->semStack[$stackPos-(10-4)], 'params' => $this->semStack[$stackPos-(10-6)], 'returnType' => $this->semStack[$stackPos-(10-8)], 'expr' => $this->semStack[$stackPos-(10-10)], 'attrGroups' => $this->semStack[$stackPos-(10-1)]], $this->startAttributeStack[$stackPos-(10-1)] + $this->endAttributes); }, - 442 => function ($stackPos) { + 441 => function ($stackPos) { $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$stackPos-(9-3)], 'params' => $this->semStack[$stackPos-(9-5)], 'uses' => $this->semStack[$stackPos-(9-7)], 'returnType' => $this->semStack[$stackPos-(9-8)], 'stmts' => $this->semStack[$stackPos-(9-9)], 'attrGroups' => $this->semStack[$stackPos-(9-1)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); }, - 443 => function ($stackPos) { + 442 => function ($stackPos) { $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$stackPos-(10-4)], 'params' => $this->semStack[$stackPos-(10-6)], 'uses' => $this->semStack[$stackPos-(10-8)], 'returnType' => $this->semStack[$stackPos-(10-9)], 'stmts' => $this->semStack[$stackPos-(10-10)], 'attrGroups' => $this->semStack[$stackPos-(10-1)]], $this->startAttributeStack[$stackPos-(10-1)] + $this->endAttributes); }, - 444 => function ($stackPos) { + 443 => function ($stackPos) { $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$stackPos-(8-4)], 'implements' => $this->semStack[$stackPos-(8-5)], 'stmts' => $this->semStack[$stackPos-(8-7)], 'attrGroups' => $this->semStack[$stackPos-(8-1)]], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes), $this->semStack[$stackPos-(8-3)]); $this->checkClass($this->semValue[0], -1); }, - 445 => function ($stackPos) { + 444 => function ($stackPos) { $this->semValue = new Expr\New_($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 446 => function ($stackPos) { + 445 => function ($stackPos) { list($class, $ctorArgs) = $this->semStack[$stackPos-(2-2)]; $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 447 => function ($stackPos) { + 446 => function ($stackPos) { $this->semValue = array(); }, - 448 => function ($stackPos) { + 447 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(4-3)]; }, - 449 => function ($stackPos) { + 448 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-1)]; }, - 450 => function ($stackPos) { + 449 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)]); }, - 451 => function ($stackPos) { + 450 => function ($stackPos) { $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; }, - 452 => function ($stackPos) { + 451 => function ($stackPos) { $this->semValue = new Expr\ClosureUse($this->semStack[$stackPos-(2-2)], $this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, + 452 => function ($stackPos) { + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, 453 => function ($stackPos) { $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, 454 => function ($stackPos) { - $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); - }, - 455 => function ($stackPos) { $this->semValue = new Expr\StaticCall($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 456 => function ($stackPos) { + 455 => function ($stackPos) { $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 457 => function ($stackPos) { + 456 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, + 457 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, 458 => function ($stackPos) { $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, 459 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); - }, - 460 => function ($stackPos) { $this->semValue = new Name\FullyQualified(substr($this->semStack[$stackPos-(1-1)], 1), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 461 => function ($stackPos) { + 460 => function ($stackPos) { $this->semValue = new Name\Relative(substr($this->semStack[$stackPos-(1-1)], 10), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, + 461 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, 462 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 463 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; - }, - 464 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(3-2)]; }, - 465 => function ($stackPos) { + 464 => function ($stackPos) { $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; }, + 465 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, 466 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 467 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; - }, - 468 => function ($stackPos) { $this->semValue = null; }, - 469 => function ($stackPos) { + 468 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(3-2)]; }, - 470 => function ($stackPos) { + 469 => function ($stackPos) { $this->semValue = array(); }, - 471 => function ($stackPos) { + 470 => function ($stackPos) { $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$stackPos-(1-1)], '`'), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes)); }, - 472 => function ($stackPos) { + 471 => function ($stackPos) { foreach ($this->semStack[$stackPos-(1-1)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', true); } }; $this->semValue = $this->semStack[$stackPos-(1-1)]; }, - 473 => function ($stackPos) { + 472 => function ($stackPos) { $this->semValue = array(); }, - 474 => function ($stackPos) { + 473 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, - 475 => function ($stackPos) { + 474 => function ($stackPos) { $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 476 => function ($stackPos) { + 475 => function ($stackPos) { $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 477 => function ($stackPos) { + 476 => function ($stackPos) { $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 478 => function ($stackPos) { + 477 => function ($stackPos) { $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 479 => function ($stackPos) { + 478 => function ($stackPos) { $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 480 => function ($stackPos) { + 479 => function ($stackPos) { $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 481 => function ($stackPos) { + 480 => function ($stackPos) { $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 482 => function ($stackPos) { + 481 => function ($stackPos) { $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 483 => function ($stackPos) { + 482 => function ($stackPos) { $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 484 => function ($stackPos) { + 483 => function ($stackPos) { $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 485 => function ($stackPos) { + 484 => function ($stackPos) { $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos-(3-1)], new Expr\Error($this->startAttributeStack[$stackPos-(3-3)] + $this->endAttributeStack[$stackPos-(3-3)]), $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->errorState = 2; }, - 486 => function ($stackPos) { + 485 => function ($stackPos) { $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_SHORT; $this->semValue = new Expr\Array_($this->semStack[$stackPos-(3-2)], $attrs); }, - 487 => function ($stackPos) { + 486 => function ($stackPos) { $attrs = $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_LONG; $this->semValue = new Expr\Array_($this->semStack[$stackPos-(4-3)], $attrs); }, - 488 => function ($stackPos) { + 487 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, - 489 => function ($stackPos) { + 488 => function ($stackPos) { $attrs = $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$stackPos-(1-1)][0] === "'" || ($this->semStack[$stackPos-(1-1)][1] === "'" && ($this->semStack[$stackPos-(1-1)][0] === 'b' || $this->semStack[$stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); $this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$stackPos-(1-1)]), $attrs); }, - 490 => function ($stackPos) { + 489 => function ($stackPos) { $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; foreach ($this->semStack[$stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', true); } }; $this->semValue = new Scalar\Encapsed($this->semStack[$stackPos-(3-2)], $attrs); }, - 491 => function ($stackPos) { + 490 => function ($stackPos) { $this->semValue = $this->parseLNumber($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 492 => function ($stackPos) { + 491 => function ($stackPos) { $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$stackPos-(1-1)]), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, + 492 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, 493 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, @@ -2489,28 +2480,28 @@ class Php7 extends \PhpParser\ParserAbstract $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 495 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; + $this->semValue = $this->parseDocString($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes, $this->startAttributeStack[$stackPos-(3-3)] + $this->endAttributeStack[$stackPos-(3-3)], true); }, 496 => function ($stackPos) { - $this->semValue = $this->parseDocString($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes, $this->startAttributeStack[$stackPos-(3-3)] + $this->endAttributeStack[$stackPos-(3-3)], true); - }, - 497 => function ($stackPos) { $this->semValue = $this->parseDocString($this->semStack[$stackPos-(2-1)], '', $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes, $this->startAttributeStack[$stackPos-(2-2)] + $this->endAttributeStack[$stackPos-(2-2)], true); }, - 498 => function ($stackPos) { + 497 => function ($stackPos) { $this->semValue = $this->parseDocString($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes, $this->startAttributeStack[$stackPos-(3-3)] + $this->endAttributeStack[$stackPos-(3-3)], true); }, - 499 => function ($stackPos) { + 498 => function ($stackPos) { $this->semValue = null; }, + 499 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, 500 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 501 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; + $this->semValue = $this->semStack[$stackPos-(3-2)]; }, 502 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(3-2)]; + $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 503 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; @@ -2525,35 +2516,35 @@ class Php7 extends \PhpParser\ParserAbstract $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 507 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; + $this->semValue = $this->semStack[$stackPos-(3-2)]; }, 508 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(3-2)]; + $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 509 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 510 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, 511 => function ($stackPos) { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, 512 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); - }, - 513 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, - 514 => function ($stackPos) { + 513 => function ($stackPos) { $this->semValue = new Expr\MethodCall($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 515 => function ($stackPos) { + 514 => function ($stackPos) { $this->semValue = new Expr\NullsafeMethodCall($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 516 => function ($stackPos) { + 515 => function ($stackPos) { $this->semValue = null; }, + 516 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, 517 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, @@ -2561,168 +2552,165 @@ class Php7 extends \PhpParser\ParserAbstract $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 519 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; - }, - 520 => function ($stackPos) { $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 521 => function ($stackPos) { + 520 => function ($stackPos) { $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, + 521 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, 522 => function ($stackPos) { - $this->semValue = substr($this->semStack[$stackPos-(1-1)], 1); + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, 523 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(4-3)]; - }, - 524 => function ($stackPos) { $this->semValue = new Expr\Variable($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, + 524 => function ($stackPos) { + $this->semValue = new Expr\Variable(new Expr\Error($this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes), $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); $this->errorState = 2; + }, 525 => function ($stackPos) { - $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); $this->errorState = 2; + $var = $this->semStack[$stackPos-(1-1)]->name; $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes) : $var; }, 526 => function ($stackPos) { - $var = $this->semStack[$stackPos-(1-1)]; $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes) : $var; - }, - 527 => function ($stackPos) { $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, + 527 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, 528 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, 529 => function ($stackPos) { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, 530 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); - }, - 531 => function ($stackPos) { $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 532 => function ($stackPos) { + 531 => function ($stackPos) { $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, + 532 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, 533 => function ($stackPos) { $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, 534 => function ($stackPos) { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 535 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(1-1)]; + $this->semValue = $this->semStack[$stackPos-(3-2)]; }, 536 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(3-2)]; - }, - 537 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); - }, - 538 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, - 539 => function ($stackPos) { + 537 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 538 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(3-2)]; }, - 540 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + 539 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; }, - 541 => function ($stackPos) { + 540 => function ($stackPos) { $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; }, - 542 => function ($stackPos) { + 541 => function ($stackPos) { $this->semValue = new Expr\List_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 543 => function ($stackPos) { + 542 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; $end = count($this->semValue)-1; if ($this->semValue[$end] === null) array_pop($this->semValue); }, - 544 => function ($stackPos) { + 543 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos]; }, - 545 => function ($stackPos) { + 544 => function ($stackPos) { /* do nothing -- prevent default action of $$=$this->semStack[$1]. See $551. */ }, - 546 => function ($stackPos) { + 545 => function ($stackPos) { $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; }, - 547 => function ($stackPos) { + 546 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)]); }, - 548 => function ($stackPos) { + 547 => function ($stackPos) { $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 549 => function ($stackPos) { + 548 => function ($stackPos) { $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(2-2)], null, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 550 => function ($stackPos) { + 549 => function ($stackPos) { $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 551 => function ($stackPos) { + 550 => function ($stackPos) { $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 552 => function ($stackPos) { + 551 => function ($stackPos) { $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-1)], true, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 553 => function ($stackPos) { + 552 => function ($stackPos) { $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 554 => function ($stackPos) { + 553 => function ($stackPos) { $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(2-2)], null, false, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 555 => function ($stackPos) { + 554 => function ($stackPos) { $this->semValue = null; }, + 555 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, 556 => function ($stackPos) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }, 557 => function ($stackPos) { - $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; - }, - 558 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)]); }, - 559 => function ($stackPos) { + 558 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); }, - 560 => function ($stackPos) { + 559 => function ($stackPos) { $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 561 => function ($stackPos) { + 560 => function ($stackPos) { $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 562 => function ($stackPos) { + 561 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, - 563 => function ($stackPos) { + 562 => function ($stackPos) { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, - 564 => function ($stackPos) { + 563 => function ($stackPos) { $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, - 565 => function ($stackPos) { + 564 => function ($stackPos) { $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, + 565 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, 566 => function ($stackPos) { $this->semValue = new Expr\Variable($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); }, 567 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); - }, - 568 => function ($stackPos) { $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-4)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); }, - 569 => function ($stackPos) { + 568 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(3-2)]; }, - 570 => function ($stackPos) { + 569 => function ($stackPos) { $this->semValue = new Scalar\String_($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 571 => function ($stackPos) { + 570 => function ($stackPos) { $this->semValue = $this->parseNumString($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, - 572 => function ($stackPos) { + 571 => function ($stackPos) { $this->semValue = $this->parseNumString('-' . $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); }, - 573 => function ($stackPos) { + 572 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; }, ]; diff --git a/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php b/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php index 11c8568db..3ff474264 100644 --- a/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php +++ b/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php @@ -219,10 +219,7 @@ abstract class ParserAbstract implements Parser )); } - // This is necessary to assign some meaningful attributes to /* empty */ productions. They'll get - // the attributes of the next token, even though they don't contain it themselves. - $this->startAttributeStack[$stackPos+1] = $startAttributes; - $this->endAttributeStack[$stackPos+1] = $endAttributes; + // Allow productions to access the start attributes of the lookahead token. $this->lookaheadStartAttributes = $startAttributes; //$this->traceRead($symbol); @@ -294,7 +291,8 @@ abstract class ParserAbstract implements Parser /* Goto - shift nonterminal */ $lastEndAttributes = $this->endAttributeStack[$stackPos]; - $stackPos -= $this->ruleToLength[$rule]; + $ruleLength = $this->ruleToLength[$rule]; + $stackPos -= $ruleLength; $nonTerminal = $this->ruleToNonTerminal[$rule]; $idx = $this->gotoBase[$nonTerminal] + $stateStack[$stackPos]; if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] === $nonTerminal) { @@ -307,6 +305,10 @@ abstract class ParserAbstract implements Parser $stateStack[$stackPos] = $state; $this->semStack[$stackPos] = $this->semValue; $this->endAttributeStack[$stackPos] = $lastEndAttributes; + if ($ruleLength === 0) { + // Empty productions use the start attributes of the lookahead token. + $this->startAttributeStack[$stackPos] = $this->lookaheadStartAttributes; + } } else { /* error */ switch ($this->errorState) { @@ -340,6 +342,7 @@ abstract class ParserAbstract implements Parser // We treat the error symbol as being empty, so we reset the end attributes // to the end attributes of the last non-error symbol + $this->startAttributeStack[$stackPos] = $this->lookaheadStartAttributes; $this->endAttributeStack[$stackPos] = $this->endAttributeStack[$stackPos - 1]; $this->endAttributes = $this->endAttributeStack[$stackPos - 1]; break; diff --git a/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php b/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php index c44bda983..636129d55 100644 --- a/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php +++ b/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php @@ -1040,7 +1040,7 @@ class Standard extends PrettyPrinterAbstract * @param Node[] $nodes * @return bool */ - private function hasNodeWithComments(array $nodes) { + protected function hasNodeWithComments(array $nodes) { foreach ($nodes as $node) { if ($node && $node->getComments()) { return true; @@ -1049,7 +1049,7 @@ class Standard extends PrettyPrinterAbstract return false; } - private function pMaybeMultiline(array $nodes, bool $trailingComma = false) { + protected function pMaybeMultiline(array $nodes, bool $trailingComma = false) { if (!$this->hasNodeWithComments($nodes)) { return $this->pCommaSeparated($nodes); } else { @@ -1057,7 +1057,7 @@ class Standard extends PrettyPrinterAbstract } } - private function pAttrGroups(array $nodes, bool $inline = false): string { + protected function pAttrGroups(array $nodes, bool $inline = false): string { $result = ''; $sep = $inline ? ' ' : $this->nl; foreach ($nodes as $node) { diff --git a/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php b/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php index bc85f76b4..804026eff 100644 --- a/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php +++ b/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php @@ -66,7 +66,7 @@ abstract class PrettyPrinterAbstract BinaryOp\BooleanAnd::class => [120, -1], BinaryOp\BooleanOr::class => [130, -1], BinaryOp\Coalesce::class => [140, 1], - Expr\Ternary::class => [150, -1], + Expr\Ternary::class => [150, 0], // parser uses %left for assignments, but they really behave as %right Expr\Assign::class => [160, 1], Expr\AssignRef::class => [160, 1], diff --git a/vendor/october/rain/composer.json b/vendor/october/rain/composer.json index 6c9414fea..63df3ed4a 100644 --- a/vendor/october/rain/composer.json +++ b/vendor/october/rain/composer.json @@ -78,7 +78,8 @@ }, "autoload-dev": { "classmap": [ - "tests/TestCase.php" + "tests/TestCase.php", + "tests/DbTestCase.php" ], "psr-4": { "October\\Rain\\Tests\\": "tests/" diff --git a/vendor/october/rain/src/Auth/Manager.php b/vendor/october/rain/src/Auth/Manager.php index 1bb65baf6..479045ef6 100644 --- a/vendor/october/rain/src/Auth/Manager.php +++ b/vendor/october/rain/src/Auth/Manager.php @@ -241,7 +241,7 @@ class Manager implements \Illuminate\Contracts\Auth\StatefulGuard foreach ($hashedCredentials as $credential => $value) { if (!$user->checkHashValue($credential, $value)) { // Incorrect password - if ($credential == 'password') { + if ($credential === 'password') { throw new AuthException(sprintf( 'A user was found to match all plain text credentials however hashed credential "%s" did not match.', $credential @@ -686,7 +686,7 @@ class Manager implements \Illuminate\Contracts\Auth\StatefulGuard $this->user = null; - Session::flush(); + Session::invalidate(); Cookie::queue(Cookie::forget($this->sessionKey)); } diff --git a/vendor/october/rain/src/Auth/Models/Role.php b/vendor/october/rain/src/Auth/Models/Role.php index a90b2ac71..92c95ce9c 100644 --- a/vendor/october/rain/src/Auth/Models/Role.php +++ b/vendor/october/rain/src/Auth/Models/Role.php @@ -84,7 +84,7 @@ class Role extends Model // We will make sure that the merged permission does not // exactly match our permission, but starts with it. - if ($checkPermission != $rolePermission && starts_with($rolePermission, $checkPermission) && $value == 1) { + if ($checkPermission != $rolePermission && starts_with($rolePermission, $checkPermission) && (int) $value === 1) { $matched = true; break; } @@ -102,7 +102,7 @@ class Role extends Model // We will make sure that the merged permission does not // exactly match our permission, but ends with it. - if ($checkPermission != $rolePermission && ends_with($rolePermission, $checkPermission) && $value == 1) { + if ($checkPermission != $rolePermission && ends_with($rolePermission, $checkPermission) && (int) $value === 1) { $matched = true; break; } @@ -121,14 +121,14 @@ class Role extends Model // We will make sure that the merged permission does not // exactly match our permission, but starts with it. - if ($checkGroupPermission != $permission && starts_with($permission, $checkGroupPermission) && $value == 1) { + if ($checkGroupPermission != $permission && starts_with($permission, $checkGroupPermission) && (int) $value === 1) { $matched = true; break; } } // Otherwise, we'll fallback to standard permissions checking where // we match that permissions explicitly exist. - elseif ($permission == $rolePermission && $rolePermissions[$permission] == 1) { + elseif ($permission === $rolePermission && (int) $rolePermissions[$permission] === 1) { $matched = true; break; } diff --git a/vendor/october/rain/src/Auth/Models/Throttle.php b/vendor/october/rain/src/Auth/Models/Throttle.php index fbaf14b2e..ba01a8645 100644 --- a/vendor/october/rain/src/Auth/Models/Throttle.php +++ b/vendor/october/rain/src/Auth/Models/Throttle.php @@ -99,7 +99,7 @@ class Throttle extends Model // anything either as clearing login attempts // makes us unsuspended. We need to manually // call unsuspend() in order to unsuspend. - if ($this->getLoginAttempts() == 0 or $this->is_suspended) { + if ($this->getLoginAttempts() === 0 or $this->is_suspended) { return; } diff --git a/vendor/october/rain/src/Auth/Models/User.php b/vendor/october/rain/src/Auth/Models/User.php index 9f86f7676..b2237f750 100644 --- a/vendor/october/rain/src/Auth/Models/User.php +++ b/vendor/october/rain/src/Auth/Models/User.php @@ -190,7 +190,7 @@ class User extends Model implements \Illuminate\Contracts\Auth\Authenticatable return false; } - return $persistCode == $this->persist_code; + return $persistCode === $this->persist_code; } // @@ -278,7 +278,7 @@ class User extends Model implements \Illuminate\Contracts\Auth\Authenticatable return false; } - return ($this->reset_password_code == $resetCode); + return ($this->reset_password_code === $resetCode); } /** @@ -386,7 +386,7 @@ class User extends Model implements \Illuminate\Contracts\Auth\Authenticatable public function inGroup($group) { foreach ($this->getGroups() as $_group) { - if ($_group->getKey() == $group->getKey()) { + if ($_group->getKey() === $group->getKey()) { return true; } } @@ -481,7 +481,7 @@ class User extends Model implements \Illuminate\Contracts\Auth\Authenticatable // We will make sure that the merged permission does not // exactly match our permission, but starts with it. - if ($checkPermission != $mergedPermission && starts_with($mergedPermission, $checkPermission) && $value == 1) { + if ($checkPermission != $mergedPermission && starts_with($mergedPermission, $checkPermission) && (int) $value === 1) { $matched = true; break; } @@ -496,7 +496,7 @@ class User extends Model implements \Illuminate\Contracts\Auth\Authenticatable // We will make sure that the merged permission does not // exactly match our permission, but ends with it. - if ($checkPermission != $mergedPermission && ends_with($mergedPermission, $checkPermission) && $value == 1) { + if ($checkPermission != $mergedPermission && ends_with($mergedPermission, $checkPermission) && (int) $value === 1) { $matched = true; break; } @@ -515,7 +515,7 @@ class User extends Model implements \Illuminate\Contracts\Auth\Authenticatable // We will make sure that the merged permission does not // exactly match our permission, but starts with it. - if ($checkMergedPermission != $permission && starts_with($permission, $checkMergedPermission) && $value == 1) { + if ($checkMergedPermission != $permission && starts_with($permission, $checkMergedPermission) && (int) $value === 1) { $matched = true; break; } @@ -523,7 +523,7 @@ class User extends Model implements \Illuminate\Contracts\Auth\Authenticatable // Otherwise, we'll fallback to standard permissions checking where // we match that permissions explicitly exist. - elseif ($permission == $mergedPermission && $mergedPermissions[$permission] == 1) { + elseif ($permission === $mergedPermission && (int) $mergedPermissions[$permission] === 1) { $matched = true; break; } diff --git a/vendor/october/rain/src/Filesystem/Definitions.php b/vendor/october/rain/src/Filesystem/Definitions.php index 931e3552e..31174b8d0 100644 --- a/vendor/october/rain/src/Filesystem/Definitions.php +++ b/vendor/october/rain/src/Filesystem/Definitions.php @@ -118,7 +118,6 @@ class Definitions 'pdf', 'swf', 'txt', - 'xml', 'ods', 'xls', 'xlsx', @@ -138,7 +137,6 @@ class Definitions 'webm', 'mkv', 'rar', - 'xml', 'zip' ]; } @@ -168,8 +166,7 @@ class Definitions 'md', 'less', 'sass', - 'scss', - 'xml' + 'scss' ]; } diff --git a/vendor/october/rain/src/Foundation/Http/Kernel.php b/vendor/october/rain/src/Foundation/Http/Kernel.php index 229d11aef..f6af6189e 100644 --- a/vendor/october/rain/src/Foundation/Http/Kernel.php +++ b/vendor/october/rain/src/Foundation/Http/Kernel.php @@ -10,13 +10,13 @@ class Kernel extends HttpKernel * @var array */ protected $bootstrappers = [ - '\October\Rain\Foundation\Bootstrap\RegisterClassLoader', - '\October\Rain\Foundation\Bootstrap\LoadEnvironmentVariables', - '\October\Rain\Foundation\Bootstrap\LoadConfiguration', - '\October\Rain\Foundation\Bootstrap\LoadTranslation', + \October\Rain\Foundation\Bootstrap\RegisterClassLoader::class, + \October\Rain\Foundation\Bootstrap\LoadEnvironmentVariables::class, + \October\Rain\Foundation\Bootstrap\LoadConfiguration::class, + \October\Rain\Foundation\Bootstrap\LoadTranslation::class, \Illuminate\Foundation\Bootstrap\HandleExceptions::class, \Illuminate\Foundation\Bootstrap\RegisterFacades::class, - '\October\Rain\Foundation\Bootstrap\RegisterOctober', + \October\Rain\Foundation\Bootstrap\RegisterOctober::class, \Illuminate\Foundation\Bootstrap\RegisterProviders::class, \Illuminate\Foundation\Bootstrap\BootProviders::class, ]; @@ -27,7 +27,8 @@ class Kernel extends HttpKernel * @var array */ protected $middleware = [ - '\October\Rain\Foundation\Http\Middleware\CheckForMaintenanceMode', + \October\Rain\Foundation\Http\Middleware\CheckForTrustedHost::class, + \October\Rain\Foundation\Http\Middleware\CheckForMaintenanceMode::class, ]; /** diff --git a/vendor/october/rain/src/Foundation/Http/Middleware/CheckForTrustedHost.php b/vendor/october/rain/src/Foundation/Http/Middleware/CheckForTrustedHost.php new file mode 100644 index 000000000..64775cf64 --- /dev/null +++ b/vendor/october/rain/src/Foundation/Http/Middleware/CheckForTrustedHost.php @@ -0,0 +1,82 @@ + [ + * 'example.com', // Matches just example.com + * 'www.example.com', // Matches just www.example.com + * '^(.+\.)?example\.com$', // Matches example.com and all subdomains + * 'https://example.com', // Matches just example.com + * ], + * + * or as a boolean - if true, it will trust the `app.url` host and all subdomains, if false it + * will disable the feature entirely. + * + * Hosts can be defined as regex patterns for complex matching. + * + * @return array + */ + public function hosts() + { + return self::processTrustedHosts(Config::get('app.trustedHosts', [])); + } + + /** + * Processes the trusted hosts into an array of patterns the match for host header checks. + * + * @param array|bool $hosts + * @return array + */ + public static function processTrustedHosts($hosts) + { + if ($hosts === true) { + $url = Config::get('app.url', null); + + // If no app URL is set, then disable trusted hosts. + if (is_null($url)) { + return []; + } + + // Allow both the domain and the `www` subdomain for app.url + // regardless of the presence of www in the app.url value + $host = parse_url($url, PHP_URL_HOST); + if (preg_match('/^www\.(.*?)$/i', $host, $matches)) { + $host = '^(www\.)?' . preg_quote($matches[1]) . '$'; + } else { + $host = '^(www\.)?' . preg_quote($host) . '$'; + } + + $hosts = [$host]; + } elseif ($hosts === false) { + return []; + } + + $hosts = array_map(function ($host) { + // If a URL is provided, extract the host + if (filter_var($host, FILTER_VALIDATE_URL)) { + $host = parse_url($host, PHP_URL_HOST); + } + + // Prepare IP address & plain hostname values to be processed by the regex filter + if ( + filter_var($host, FILTER_VALIDATE_IP) + || filter_var($host, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) + ) { + return '^' . preg_quote($host) . '$'; + } + + // Allow everything else through as is + return $host; + }, $hosts); + + return $hosts; + } +} diff --git a/vendor/october/rain/src/Http/Middleware/TrustHosts.php b/vendor/october/rain/src/Http/Middleware/TrustHosts.php new file mode 100644 index 000000000..70381843b --- /dev/null +++ b/vendor/october/rain/src/Http/Middleware/TrustHosts.php @@ -0,0 +1,71 @@ +app = $app; + } + + /** + * Get the host patterns that should be trusted. + * + * @return array + */ + abstract public function hosts(); + + /** + * Handle the incoming request. + * + * @param \Illuminate\Http\Request $request + * @param callable $next + * @return \Illuminate\Http\Response + */ + public function handle(Request $request, $next) + { + if ($this->shouldSpecifyTrustedHosts()) { + Request::setTrustedHosts(array_filter($this->hosts())); + } + + return $next($request); + } + + /** + * Determine if the application should specify trusted hosts. + * + * @return bool + */ + protected function shouldSpecifyTrustedHosts() + { + return $this->app['config']->get('app.env') !== 'local' + && $this->app->runningUnitTests() === false; + } + + /** + * Get a regular expression matching the application URL and all of its subdomains. + * + * @return string|null + */ + protected function allSubdomainsOfApplicationUrl() + { + if ($host = parse_url($this->app['config']->get('app.url'), PHP_URL_HOST)) { + return '^(.+\.)?'.preg_quote($host).'$'; + } + } +} diff --git a/vendor/october/rain/tests/Database/SortableTest.php b/vendor/october/rain/tests/Database/SortableTest.php index bbad6e09f..a7ace3400 100644 --- a/vendor/october/rain/tests/Database/SortableTest.php +++ b/vendor/october/rain/tests/Database/SortableTest.php @@ -1,22 +1,10 @@ addConnection([ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => '' - ]); - $capsule->setAsGlobal(); - $capsule->bootEloquent(); - } - public function testOrderByIsAutomaticallyAdded() { - $model = new TestModel(); + $model = new TestSortableModel(); $query = $model->newQuery()->toSql(); $this->assertEquals('select * from "test" order by "sort_order" asc', $query); @@ -24,7 +12,7 @@ class SortableTest extends TestCase public function testOrderByCanBeOverridden() { - $model = new TestModel(); + $model = new TestSortableModel(); $query1 = $model->newQuery()->orderBy('name')->orderBy('email', 'desc')->toSql(); $query2 = $model->newQuery()->orderBy('sort_order')->orderBy('name')->toSql(); @@ -33,7 +21,7 @@ class SortableTest extends TestCase } } -class TestModel extends \October\Rain\Database\Model +class TestSortableModel extends \October\Rain\Database\Model { use \October\Rain\Database\Traits\Sortable; diff --git a/vendor/october/rain/tests/Database/Traits/EncryptableTest.php b/vendor/october/rain/tests/Database/Traits/EncryptableTest.php index 94bed0b4c..9ff2ff106 100644 --- a/vendor/october/rain/tests/Database/Traits/EncryptableTest.php +++ b/vendor/october/rain/tests/Database/Traits/EncryptableTest.php @@ -2,7 +2,7 @@ use Illuminate\Encryption\Encrypter; -class EncryptableTest extends TestCase +class EncryptableTest extends DbTestCase { const TEST_CRYPT_KEY = 'gBmM1S5bxZ5ePRj5'; @@ -13,21 +13,8 @@ class EncryptableTest extends TestCase public function setUp() { - $capsule = new Illuminate\Database\Capsule\Manager; - $capsule->addConnection([ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => '' - ]); - - $capsule->setAsGlobal(); - $capsule->bootEloquent(); - - $capsule->schema()->create('secrets', function ($table) { - $table->increments('id'); - $table->string('secret'); - $table->timestamps(); - }); + parent::setUp(); + $this->createTable(); $this->encrypter = new Encrypter(self::TEST_CRYPT_KEY, 'AES-128-CBC'); } @@ -61,6 +48,15 @@ class EncryptableTest extends TestCase $this->assertNull($testModel->secret); $this->assertNull($testModel->attributes['secret']); } + + protected function createTable() + { + $this->db->schema()->create('secrets', function ($table) { + $table->increments('id'); + $table->string('secret'); + $table->timestamps(); + }); + } } class TestModelEncryptable extends \October\Rain\Database\Model diff --git a/vendor/october/rain/tests/Database/Traits/PurgeableTraitTest.php b/vendor/october/rain/tests/Database/Traits/PurgeableTraitTest.php new file mode 100644 index 000000000..15ff106db --- /dev/null +++ b/vendor/october/rain/tests/Database/Traits/PurgeableTraitTest.php @@ -0,0 +1,56 @@ +createTables(); + } + + public function testPurgeable() + { + // Mass-assignment + $model = TestModelPurgeable::create([ + 'name' => 'Test', + 'confirmed' => true + ]); + + $this->assertNull($model->confirmed); + + // Direct assignment + $model = new TestModelPurgeable(); + $model->name = 'Test'; + $model->confirmed = true; + + $this->assertTrue($model->confirmed); + + $model->save(); + + $this->assertNull($model->confirmed); + } + + protected function createTables() + { + $this->db->schema()->create('test_purge', function ($table) { + $table->increments('id'); + $table->string('name'); + $table->string('data')->nullable(); + $table->timestamps(); + }); + } +} + +class TestModelPurgeable extends Model +{ + use \October\Rain\Database\Traits\Purgeable; + + protected $guarded = ['data']; + + protected $purgeable = ['confirmed']; + + protected $table = 'test_purge'; +} diff --git a/vendor/october/rain/tests/Database/Traits/SluggableTest.php b/vendor/october/rain/tests/Database/Traits/SluggableTest.php index 4411ce1ee..a09d7987e 100644 --- a/vendor/october/rain/tests/Database/Traits/SluggableTest.php +++ b/vendor/october/rain/tests/Database/Traits/SluggableTest.php @@ -1,51 +1,13 @@ addConnection([ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => '' - ]); + parent::setUp(); - # Create the dataset in the connection with the tables - $capsule->setAsGlobal(); - $capsule->bootEloquent(); - - $capsule->schema()->create('testSoftDelete', function ($table) { - $table->increments('id'); - $table->string('name'); - $table->string('slug')->unique(); - $table->softDeletes(); - $table->timestamps(); - }); - - $capsule->schema()->create('testSoftDeleteNoUnique', function ($table) { - $table->increments('id'); - $table->string('name'); - $table->string('slug'); - $table->softDeletes(); - $table->timestamps(); - }); - - $capsule->schema()->create('testSoftDeleteAllow', function ($table) { - $table->increments('id'); - $table->string('name'); - $table->string('slug')->unique(); - $table->softDeletes(); - $table->timestamps(); - }); - - $capsule->schema()->create('test', function ($table) { - $table->increments('id'); - $table->string('name'); - $table->string('slug')->unique(); - $table->timestamps(); - }); + $this->createTables(); } public function testSlugGeneration() @@ -176,6 +138,41 @@ class SluggableTest extends TestCase $testModel2 = TestModelSluggable::Create(['name' => 'test']); $this->assertEquals($testModel2->slug, 'test'); } + + + protected function createTables() + { + $this->db->schema()->create('testSoftDelete', function ($table) { + $table->increments('id'); + $table->string('name'); + $table->string('slug')->unique(); + $table->softDeletes(); + $table->timestamps(); + }); + + $this->db->schema()->create('testSoftDeleteNoUnique', function ($table) { + $table->increments('id'); + $table->string('name'); + $table->string('slug'); + $table->softDeletes(); + $table->timestamps(); + }); + + $this->db->schema()->create('testSoftDeleteAllow', function ($table) { + $table->increments('id'); + $table->string('name'); + $table->string('slug')->unique(); + $table->softDeletes(); + $table->timestamps(); + }); + + $this->db->schema()->create('test', function ($table) { + $table->increments('id'); + $table->string('name'); + $table->string('slug')->unique(); + $table->timestamps(); + }); + } } /* diff --git a/vendor/october/rain/tests/DbTestCase.php b/vendor/october/rain/tests/DbTestCase.php index 35008f996..d7e74188a 100644 --- a/vendor/october/rain/tests/DbTestCase.php +++ b/vendor/october/rain/tests/DbTestCase.php @@ -2,12 +2,12 @@ use October\Rain\Database\Model; use October\Rain\Database\Pivot; -use October\Rain\Database\Capsule\Manager as CapsuleManager; +use Illuminate\Database\Capsule\Manager as CapsuleManager; use October\Rain\Events\Dispatcher; class DbTestCase extends TestCase { - public function setUp(): void + public function setUp() { $this->db = new CapsuleManager; $this->db->addConnection([ @@ -22,7 +22,7 @@ class DbTestCase extends TestCase Model::setEventDispatcher(new Dispatcher()); } - public function tearDown(): void + public function tearDown() { $this->flushModelEventListeners(); parent::tearDown(); diff --git a/vendor/psr/container/README.md b/vendor/psr/container/README.md index 084f6df51..1b9d9e570 100644 --- a/vendor/psr/container/README.md +++ b/vendor/psr/container/README.md @@ -1,5 +1,13 @@ -# PSR Container +Container interface +============== -This repository holds all interfaces/classes/traits related to [PSR-11](https://github.com/container-interop/fig-standards/blob/master/proposed/container.md). +This repository holds all interfaces related to [PSR-11 (Container Interface)][psr-url]. + +Note that this is not a Container implementation of its own. It is merely abstractions that describe the components of a Dependency Injection Container. + +The installable [package][package-url] and [implementations][implementation-url] are listed on Packagist. + +[psr-url]: https://www.php-fig.org/psr/psr-11/ +[package-url]: https://packagist.org/packages/psr/container +[implementation-url]: https://packagist.org/providers/psr/container-implementation -Note that this is not a container implementation of its own. See the specification for more details. diff --git a/vendor/psr/container/composer.json b/vendor/psr/container/composer.json index b8ee01265..3797a2538 100644 --- a/vendor/psr/container/composer.json +++ b/vendor/psr/container/composer.json @@ -8,20 +8,15 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" } - }, - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } } } diff --git a/vendor/psr/container/src/ContainerExceptionInterface.php b/vendor/psr/container/src/ContainerExceptionInterface.php index d35c6b4d8..cf10b8b4f 100644 --- a/vendor/psr/container/src/ContainerExceptionInterface.php +++ b/vendor/psr/container/src/ContainerExceptionInterface.php @@ -1,7 +1,4 @@ =7.0.0", - "egulias/email-validator": "~2.0", + "egulias/email-validator": "^2.0|^3.1", "symfony/polyfill-iconv": "^1.0", "symfony/polyfill-mbstring": "^1.0", "symfony/polyfill-intl-idn": "^1.10" }, "require-dev": { - "mockery/mockery": "~0.9.1", - "symfony/phpunit-bridge": "^3.4.19|^4.1.8" + "mockery/mockery": "^1.0", + "symfony/phpunit-bridge": "^4.4|^5.0" }, "suggest": { - "ext-intl": "Needed to support internationalized email addresses", - "true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed" + "ext-intl": "Needed to support internationalized email addresses" }, "autoload": { "files": ["lib/swift_required.php"] diff --git a/vendor/swiftmailer/swiftmailer/doc/introduction.rst b/vendor/swiftmailer/swiftmailer/doc/introduction.rst index 774e9f466..8c61cfb2e 100644 --- a/vendor/swiftmailer/swiftmailer/doc/introduction.rst +++ b/vendor/swiftmailer/swiftmailer/doc/introduction.rst @@ -1,7 +1,7 @@ Introduction ============ -Swift Mailer is a for sending e-mails from PHP applications. +Swift Mailer is a component based library for sending e-mails from PHP applications. System Requirements ------------------- diff --git a/vendor/swiftmailer/swiftmailer/doc/messages.rst b/vendor/swiftmailer/swiftmailer/doc/messages.rst index a3431a47c..53c5b36f5 100644 --- a/vendor/swiftmailer/swiftmailer/doc/messages.rst +++ b/vendor/swiftmailer/swiftmailer/doc/messages.rst @@ -100,7 +100,7 @@ with a strict format, you only need to pass a DateTimeInterface instance to +-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ | ``Date`` | Specifies the date at which the message was sent | ``getDate()`` / ``setDate()`` | +-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ -| ``Content-Type`` | Specifies the format of the message (usually text/plain or text/html) | ``getContentType()`` / ``setContentType()`` | +| ``Content-Type`` | Specifies the format of the message (usually ``text/plain`` or ``text/html``) | ``getContentType()`` / ``setContentType()`` | +-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ | ``Content-Transfer-Encoding`` | Specifies the encoding scheme in the message | ``getEncoder()`` / ``setEncoder()`` | +-------------------------------+------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------+ @@ -820,7 +820,7 @@ Requesting a Read Receipt It is possible to request a read-receipt to be sent to an address when the email is opened. To request a read receipt set the address with -``setReadReceiptTo()``: +``setReadReceiptTo()``:: $message->setReadReceiptTo('your@address.tld'); diff --git a/vendor/swiftmailer/swiftmailer/doc/sending.rst b/vendor/swiftmailer/swiftmailer/doc/sending.rst index 010420797..d3a10ad21 100644 --- a/vendor/swiftmailer/swiftmailer/doc/sending.rst +++ b/vendor/swiftmailer/swiftmailer/doc/sending.rst @@ -95,7 +95,8 @@ within your application and adjust the settings accordingly if the code is moved or if the SMTP server is changed. Some SMTP servers -- Google for example -- use encryption for security reasons. -Swift Mailer supports using both SSL and TLS encryption settings. +Swift Mailer supports using both ``ssl`` (SMTPS = SMTP over TLS) and ``tls`` +(SMTP with STARTTLS) encryption settings. Using the SMTP Transport ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -129,11 +130,14 @@ A connection to the SMTP server will be established upon the first call to Encrypted SMTP ^^^^^^^^^^^^^^ -You can use SSL or TLS encryption with the SMTP Transport by specifying it as a -parameter or with a method call:: +You can use ``ssl`` (SMTPS) or ``tls`` (STARTTLS) encryption with the SMTP Transport +by specifying it as a parameter or with a method call:: // Create the Transport + // Option #1: SMTPS = SMTP over TLS (always encrypted): $transport = new Swift_SmtpTransport('smtp.example.org', 587, 'ssl'); + // Option #2: SMTP with STARTTLS (best effort encryption): + $transport = new Swift_SmtpTransport('smtp.example.org', 587, 'tls'); // Create the Mailer using your created Transport $mailer = new Swift_Mailer($transport); @@ -143,8 +147,7 @@ A connection to the SMTP server will be established upon the first call to settings. .. note:: - - For SSL or TLS encryption to work your PHP installation must have + For SMTPS or STARTTLS encryption to work your PHP installation must have appropriate OpenSSL transports wrappers. You can check if "tls" and/or "ssl" are present in your PHP installation by using the PHP function ``stream_get_transports()``. @@ -153,6 +156,14 @@ settings. If you are using Mailcatcher_, make sure you do not set the encryption for the ``Swift_SmtpTransport``, since Mailcatcher does not support encryption. +.. note:: + When in doubt, try ``ssl`` first for higher security, since the communication + is always encrypted. + +.. note:: + Usually, port 587 or 465 is used for encrypted SMTP. Check the documentation + of your mail provider. + SMTP with a Username and Password ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php index daf75fbd4..ffe5a4885 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php @@ -15,7 +15,7 @@ */ abstract class Swift { - const VERSION = '6.2.3'; + const VERSION = '6.2.7'; public static $initialized = false; public static $inits = []; @@ -56,7 +56,7 @@ abstract class Swift if (self::$inits && !self::$initialized) { self::$initialized = true; foreach (self::$inits as $init) { - call_user_func($init); + \call_user_func($init); } } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoder.php index 7ec3e90b4..a1704ffb4 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoder.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoder.php @@ -18,8 +18,8 @@ interface Swift_AddressEncoder /** * Encodes an email address. * - * @throws Swift_AddressEncoderException If the email cannot be represented in - * the encoding implemented by this class. + * @throws Swift_AddressEncoderException if the email cannot be represented in + * the encoding implemented by this class */ public function encodeString(string $address): string; } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Attachment.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Attachment.php index 642aa6f23..7a1420f79 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Attachment.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Attachment.php @@ -26,7 +26,7 @@ class Swift_Attachment extends Swift_Mime_Attachment */ public function __construct($data = null, $filename = null, $contentType = null) { - call_user_func_array( + \call_user_func_array( [$this, 'Swift_Mime_Attachment::__construct'], Swift_DependencyContainer::getInstance() ->createDependenciesFor('mime.attachment') diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php index 68dc3b1ec..4f3dcc377 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php @@ -52,10 +52,10 @@ class Swift_ByteStream_ArrayByteStream implements Swift_InputByteStream, Swift_O */ public function __construct($stack = null) { - if (is_array($stack)) { + if (\is_array($stack)) { $this->array = $stack; - $this->arraySize = count($stack); - } elseif (is_string($stack)) { + $this->arraySize = \count($stack); + } elseif (\is_string($stack)) { $this->write($stack); } else { $this->array = []; @@ -102,7 +102,7 @@ class Swift_ByteStream_ArrayByteStream implements Swift_InputByteStream, Swift_O foreach ($to_add as $value) { $this->array[] = $value; } - $this->arraySize = count($this->array); + $this->arraySize = \count($this->array); foreach ($this->mirrors as $stream) { $stream->write($bytes); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php index 0c428f796..f6391219e 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/FileByteStream.php @@ -81,7 +81,7 @@ class Swift_ByteStream_FileByteStream extends Swift_ByteStream_AbstractFilterabl // If we read one byte after reaching the end of the file // feof() will return false and an empty string is returned - if ('' === $bytes && feof($fp)) { + if ((false === $bytes || '' === $bytes) && feof($fp)) { $this->resetReadHandle(); return false; @@ -145,9 +145,7 @@ class Swift_ByteStream_FileByteStream extends Swift_ByteStream_AbstractFilterabl { if (!isset($this->writer)) { if (!$this->writer = fopen($this->path, $this->mode)) { - throw new Swift_IoException( - 'Unable to open file for writing ['.$this->path.']' - ); + throw new Swift_IoException('Unable to open file for writing ['.$this->path.']'); } } @@ -194,7 +192,7 @@ class Swift_ByteStream_FileByteStream extends Swift_ByteStream_AbstractFilterabl { if ($tmpFile = fopen('php://temp/maxmemory:4096', 'w+b')) { /* We have opened a php:// Stream Should work without problem */ - } elseif (function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir()) && ($tmpFile = tmpfile())) { + } elseif (\function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir()) && ($tmpFile = tmpfile())) { /* We have opened a tmpfile */ } else { throw new Swift_IoException('Unable to copy the file to make it seekable, sys_temp_dir is not writable, php://memory not available'); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/TemporaryFileByteStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/TemporaryFileByteStream.php index 2d00b6a0f..0dc61909d 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/TemporaryFileByteStream.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/TemporaryFileByteStream.php @@ -39,4 +39,14 @@ class Swift_ByteStream_TemporaryFileByteStream extends Swift_ByteStream_FileByte @unlink($this->getPath()); } } + + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php index b09bb5b6c..3e055afd9 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/GenericFixedWidthReader.php @@ -45,7 +45,7 @@ class Swift_CharacterReader_GenericFixedWidthReader implements Swift_CharacterRe */ public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) { - $strlen = strlen($string); + $strlen = \strlen($string); // % and / are CPU intensive, so, maybe find a better way $ignored = $strlen % $this->width; $ignoredChars = $ignored ? substr($string, -$ignored) : ''; diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php index 67da48f6c..ffc05f716 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/UsAsciiReader.php @@ -27,7 +27,7 @@ class Swift_CharacterReader_UsAsciiReader implements Swift_CharacterReader */ public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars) { - $strlen = strlen($string); + $strlen = \strlen($string); $ignoredChars = ''; for ($i = 0; $i < $strlen; ++$i) { if ($string[$i] > "\x07F") { @@ -65,7 +65,7 @@ class Swift_CharacterReader_UsAsciiReader implements Swift_CharacterReader public function validateByteSequence($bytes, $size) { $byte = reset($bytes); - if (1 == count($bytes) && $byte >= 0x00 && $byte <= 0x7F) { + if (1 == \count($bytes) && $byte >= 0x00 && $byte <= 0x7F) { return 0; } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php index 4a2df31db..da37e0da9 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReader/Utf8Reader.php @@ -18,7 +18,7 @@ class Swift_CharacterReader_Utf8Reader implements Swift_CharacterReader { /** Pre-computed for optimization */ private static $length_map = [ - // N=0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, + // N=0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x0N 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x1N 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x2N @@ -34,7 +34,7 @@ class Swift_CharacterReader_Utf8Reader implements Swift_CharacterReader 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xCN 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xDN 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xEN - 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0, // 0xFN + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0, // 0xFN ]; private static $s_length_map = [ @@ -88,8 +88,8 @@ class Swift_CharacterReader_Utf8Reader implements Swift_CharacterReader $currentMap['p'] = $currentMap['i'] = []; } - $strlen = strlen($string); - $charPos = count($currentMap['p']); + $strlen = \strlen($string); + $charPos = \count($currentMap['p']); $foundChars = 0; $invalid = false; for ($i = 0; $i < $strlen; ++$i) { diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php index 78fffa987..debab675f 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php @@ -44,7 +44,7 @@ class Swift_CharacterReaderFactory_SimpleCharacterReaderFactory implements Swift public function init() { - if (count(self::$map) > 0) { + if (\count(self::$map) > 0) { return; } @@ -107,7 +107,7 @@ class Swift_CharacterReaderFactory_SimpleCharacterReaderFactory implements Swift foreach (self::$map as $pattern => $spec) { $re = '/^'.$pattern.'$/D'; if (preg_match($re, $charset)) { - if (!array_key_exists($pattern, self::$loaded)) { + if (!\array_key_exists($pattern, self::$loaded)) { $reflector = new ReflectionClass($spec['class']); if ($reflector->getConstructor()) { $reader = $reflector->newInstanceArgs($spec['constructor']); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream.php index 717924f5d..c9d8a078e 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream.php @@ -28,8 +28,6 @@ interface Swift_CharacterStream /** * Set the CharacterReaderFactory for multi charset support. - * - * @param Swift_CharacterReaderFactory $factory */ public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php index 887658c53..5c2869455 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php @@ -86,15 +86,15 @@ class Swift_CharacterStream_ArrayCharacterStream implements Swift_CharacterStrea $startLength = $this->charReader->getInitialByteSize(); while (false !== $bytes = $os->read($startLength)) { $c = []; - for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) { + for ($i = 0, $len = \strlen($bytes); $i < $len; ++$i) { $c[] = self::$byteMap[$bytes[$i]]; } - $size = count($c); + $size = \count($c); $need = $this->charReader ->validateByteSequence($c, $size); if ($need > 0 && false !== $bytes = $os->read($need)) { - for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) { + for ($i = 0, $len = \strlen($bytes); $i < $len; ++$i) { $c[] = self::$byteMap[$bytes[$i]]; } } @@ -204,7 +204,7 @@ class Swift_CharacterStream_ArrayCharacterStream implements Swift_CharacterStrea $new = $this->reloadBuffer($fp, 100); if ($new) { $buffer = array_merge($buf, $new); - $buf_len = count($buffer); + $buf_len = \count($buffer); $buf_pos = 0; } else { $has_datas = false; @@ -224,7 +224,7 @@ class Swift_CharacterStream_ArrayCharacterStream implements Swift_CharacterStrea if ($new) { $buffer = array_merge($buffer, $new); - $buf_len = count($buffer); + $buf_len = \count($buffer); } } for ($i = 0; $i < $need && isset($buffer[$buf_pos]); ++$i) { @@ -268,7 +268,7 @@ class Swift_CharacterStream_ArrayCharacterStream implements Swift_CharacterStrea { if (!feof($fp) && false !== ($bytes = fread($fp, $len))) { $buf = []; - for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) { + for ($i = 0, $len = \strlen($bytes); $i < $len; ++$i) { $buf[] = self::$byteMap[$bytes[$i]]; } @@ -283,7 +283,7 @@ class Swift_CharacterStream_ArrayCharacterStream implements Swift_CharacterStrea if (!isset(self::$charMap)) { self::$charMap = []; for ($byte = 0; $byte < 256; ++$byte) { - self::$charMap[$byte] = chr($byte); + self::$charMap[$byte] = \chr($byte); } self::$byteMap = array_flip(self::$charMap); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php index a733063c9..7578dda9c 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php @@ -254,9 +254,9 @@ class Swift_CharacterStream_NgCharacterStream implements Swift_CharacterStream $this->datas .= $chars; $this->charCount += $this->charReader->getCharPositions(substr($this->datas, $this->datasSize), $this->datasSize, $this->map, $ignored); if (false !== $ignored) { - $this->datasSize = strlen($this->datas) - strlen($ignored); + $this->datasSize = \strlen($this->datas) - \strlen($ignored); } else { - $this->datasSize = strlen($this->datas); + $this->datasSize = \strlen($this->datas); } } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyContainer.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyContainer.php index b38f8ce51..3cc885ec0 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyContainer.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyContainer.php @@ -83,7 +83,7 @@ class Swift_DependencyContainer */ public function has($itemName) { - return array_key_exists($itemName, $this->store) + return \array_key_exists($itemName, $this->store) && isset($this->store[$itemName]['lookupType']); } @@ -101,9 +101,7 @@ class Swift_DependencyContainer public function lookup($itemName) { if (!$this->has($itemName)) { - throw new Swift_DependencyException( - 'Cannot lookup dependency "'.$itemName.'" since it is not registered.' - ); + throw new Swift_DependencyException('Cannot lookup dependency "'.$itemName.'" since it is not registered.'); } switch ($this->store[$itemName]['lookupType']) { @@ -348,9 +346,7 @@ class Swift_DependencyContainer private function &getEndPoint() { if (!isset($this->endPoint)) { - throw new BadMethodCallException( - 'Component must first be registered by calling register()' - ); + throw new BadMethodCallException('Component must first be registered by calling register()'); } return $this->endPoint; @@ -377,7 +373,7 @@ class Swift_DependencyContainer /** Resolve a single dependency with an collections */ private function lookupRecursive($item) { - if (is_array($item)) { + if (\is_array($item)) { $collection = []; foreach ($item as $k => $v) { $collection[$k] = $this->lookupRecursive($v); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/EmbeddedFile.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/EmbeddedFile.php index 20b81412e..30fc68ab0 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/EmbeddedFile.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/EmbeddedFile.php @@ -26,7 +26,7 @@ class Swift_EmbeddedFile extends Swift_Mime_EmbeddedFile */ public function __construct($data = null, $filename = null, $contentType = null) { - call_user_func_array( + \call_user_func_array( [$this, 'Swift_Mime_EmbeddedFile::__construct'], Swift_DependencyContainer::getInstance() ->createDependenciesFor('mime.embeddedfile') diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php index 95b4ae97b..f078d6d7c 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php @@ -135,14 +135,14 @@ class Swift_Encoder_QpEncoder implements Swift_Encoder protected function getSafeMapShareId() { - return get_class($this); + return static::class; } protected function initSafeMap() { foreach (array_merge( [0x09, 0x20], range(0x21, 0x3C), range(0x3E, 0x7E)) as $byte) { - $this->safeMap[$byte] = chr($byte); + $this->safeMap[$byte] = \chr($byte); } } @@ -281,7 +281,7 @@ class Swift_Encoder_QpEncoder implements Swift_Encoder $string = str_replace(["\t=0D=0A", ' =0D=0A', '=0D=0A'], ["=09\r\n", "=20\r\n", "\r\n"], $string ); - switch ($end = ord(substr($string, -1))) { + switch ($end = \ord(substr($string, -1))) { case 0x09: case 0x20: $string = substr_replace($string, self::$qpMap[$end], -1); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php index 2458515ad..7eac36813 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php @@ -58,8 +58,8 @@ class Swift_Encoder_Rfc2231Encoder implements Swift_Encoder while (false !== $char = $this->charStream->read(4)) { $encodedChar = rawurlencode($char); - if (0 != strlen($currentLine) - && strlen($currentLine.$encodedChar) > $thisLineLength) { + if (0 != \strlen($currentLine) + && \strlen($currentLine.$encodedChar) > $thisLineLength) { $lines[] = ''; $currentLine = &$lines[$lineCount++]; $thisLineLength = $maxLineLength; diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandListener.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandListener.php index 7545404e7..b158eab46 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandListener.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/CommandListener.php @@ -17,8 +17,6 @@ interface Swift_Events_CommandListener extends Swift_Events_EventListener { /** * Invoked immediately following a command being sent. - * - * @param Swift_Events_CommandEvent $evt */ public function commandSent(Swift_Events_CommandEvent $evt); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php index a01dfa260..df25a1248 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php @@ -18,9 +18,6 @@ interface Swift_Events_EventDispatcher /** * Create a new SendEvent for $source and $message. * - * @param Swift_Transport $source - * @param Swift_Mime_SimpleMessage - * * @return Swift_Events_SendEvent */ public function createSendEvent(Swift_Transport $source, Swift_Mime_SimpleMessage $message); @@ -28,9 +25,8 @@ interface Swift_Events_EventDispatcher /** * Create a new CommandEvent for $source and $command. * - * @param Swift_Transport $source - * @param string $command That will be executed - * @param array $successCodes That are needed + * @param string $command That will be executed + * @param array $successCodes That are needed * * @return Swift_Events_CommandEvent */ @@ -39,9 +35,8 @@ interface Swift_Events_EventDispatcher /** * Create a new ResponseEvent for $source and $response. * - * @param Swift_Transport $source - * @param string $response - * @param bool $valid If the response is valid + * @param string $response + * @param bool $valid If the response is valid * * @return Swift_Events_ResponseEvent */ @@ -50,8 +45,6 @@ interface Swift_Events_EventDispatcher /** * Create a new TransportChangeEvent for $source. * - * @param Swift_Transport $source - * * @return Swift_Events_TransportChangeEvent */ public function createTransportChangeEvent(Swift_Transport $source); @@ -59,25 +52,19 @@ interface Swift_Events_EventDispatcher /** * Create a new TransportExceptionEvent for $source. * - * @param Swift_Transport $source - * @param Swift_TransportException $ex - * * @return Swift_Events_TransportExceptionEvent */ public function createTransportExceptionEvent(Swift_Transport $source, Swift_TransportException $ex); /** * Bind an event listener to this dispatcher. - * - * @param Swift_Events_EventListener $listener */ public function bindEventListener(Swift_Events_EventListener $listener); /** * Dispatch the given Event to all suitable listeners. * - * @param Swift_Events_EventObject $evt - * @param string $target method + * @param string $target method */ public function dispatchEvent(Swift_Events_EventObject $evt, $target); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseListener.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseListener.php index c40919d21..85115a338 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseListener.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/ResponseListener.php @@ -17,8 +17,6 @@ interface Swift_Events_ResponseListener extends Swift_Events_EventListener { /** * Invoked immediately following a response coming back. - * - * @param Swift_Events_ResponseEvent $evt */ public function responseReceived(Swift_Events_ResponseEvent $evt); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SendListener.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SendListener.php index d922e1bfa..f7bf55ef5 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SendListener.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SendListener.php @@ -17,15 +17,11 @@ interface Swift_Events_SendListener extends Swift_Events_EventListener { /** * Invoked immediately before the Message is sent. - * - * @param Swift_Events_SendEvent $evt */ public function beforeSendPerformed(Swift_Events_SendEvent $evt); /** * Invoked immediately after the Message is sent. - * - * @param Swift_Events_SendEvent $evt */ public function sendPerformed(Swift_Events_SendEvent $evt); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php index 1396f6164..6557103c9 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php @@ -21,9 +21,6 @@ class Swift_Events_SimpleEventDispatcher implements Swift_Events_EventDispatcher /** Event listeners bound to this dispatcher */ private $listeners = []; - /** Listeners queued to have an Event bubbled up the stack to them */ - private $bubbleQueue = []; - /** * Create a new EventDispatcher. */ @@ -115,29 +112,31 @@ class Swift_Events_SimpleEventDispatcher implements Swift_Events_EventDispatcher */ public function dispatchEvent(Swift_Events_EventObject $evt, $target) { - $this->prepareBubbleQueue($evt); - $this->bubble($evt, $target); + $bubbleQueue = $this->prepareBubbleQueue($evt); + $this->bubble($bubbleQueue, $evt, $target); } /** Queue listeners on a stack ready for $evt to be bubbled up it */ private function prepareBubbleQueue(Swift_Events_EventObject $evt) { - $this->bubbleQueue = []; - $evtClass = get_class($evt); + $bubbleQueue = []; + $evtClass = \get_class($evt); foreach ($this->listeners as $listener) { - if (array_key_exists($evtClass, $this->eventMap) + if (\array_key_exists($evtClass, $this->eventMap) && ($listener instanceof $this->eventMap[$evtClass])) { - $this->bubbleQueue[] = $listener; + $bubbleQueue[] = $listener; } } + + return $bubbleQueue; } /** Bubble $evt up the stack calling $target() on each listener */ - private function bubble(Swift_Events_EventObject $evt, $target) + private function bubble(array &$bubbleQueue, Swift_Events_EventObject $evt, $target) { - if (!$evt->bubbleCancelled() && $listener = array_shift($this->bubbleQueue)) { + if (!$evt->bubbleCancelled() && $listener = array_shift($bubbleQueue)) { $listener->$target($evt); - $this->bubble($evt, $target); + $this->bubble($bubbleQueue, $evt, $target); } } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php index 253165de8..4a7492bc5 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeListener.php @@ -17,29 +17,21 @@ interface Swift_Events_TransportChangeListener extends Swift_Events_EventListene { /** * Invoked just before a Transport is started. - * - * @param Swift_Events_TransportChangeEvent $evt */ public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt); /** * Invoked immediately after the Transport is started. - * - * @param Swift_Events_TransportChangeEvent $evt */ public function transportStarted(Swift_Events_TransportChangeEvent $evt); /** * Invoked just before a Transport is stopped. - * - * @param Swift_Events_TransportChangeEvent $evt */ public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt); /** * Invoked immediately after the Transport is stopped. - * - * @param Swift_Events_TransportChangeEvent $evt */ public function transportStopped(Swift_Events_TransportChangeEvent $evt); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php index cc3c09937..ad80eb01d 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionListener.php @@ -17,8 +17,6 @@ interface Swift_Events_TransportExceptionListener extends Swift_Events_EventList { /** * Invoked as a TransportException is thrown in the Transport system. - * - * @param Swift_Events_TransportExceptionEvent $evt */ public function exceptionThrown(Swift_Events_TransportExceptionEvent $evt); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FailoverTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FailoverTransport.php index 0044be59b..af0be9179 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FailoverTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FailoverTransport.php @@ -22,7 +22,7 @@ class Swift_FailoverTransport extends Swift_Transport_FailoverTransport */ public function __construct($transports = []) { - call_user_func_array( + \call_user_func_array( [$this, 'Swift_Transport_FailoverTransport::__construct'], Swift_DependencyContainer::getInstance() ->createDependenciesFor('transport.failover') diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileSpool.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileSpool.php index d16c47cd6..7af8471c9 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileSpool.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/FileSpool.php @@ -198,7 +198,7 @@ class Swift_FileSpool extends Swift_ConfigurableSpool // This string MUST stay FS safe, avoid special chars $base = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-'; $ret = ''; - $strlen = strlen($base); + $strlen = \strlen($base); for ($i = 0; $i < $count; ++$i) { $ret .= $base[random_int(0, $strlen - 1)]; } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Filterable.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Filterable.php index 6b75b5274..efa1b1def 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Filterable.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Filterable.php @@ -18,8 +18,7 @@ interface Swift_Filterable /** * Add a new StreamFilter, referenced by $key. * - * @param Swift_StreamFilter $filter - * @param string $key + * @param string $key */ public function addFilter(Swift_StreamFilter $filter, $key); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache.php index cd6f786df..87f6a0742 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache.php @@ -38,10 +38,9 @@ interface Swift_KeyCache * * @see MODE_WRITE, MODE_APPEND * - * @param string $nsKey - * @param string $itemKey - * @param Swift_OutputByteStream $os - * @param int $mode + * @param string $nsKey + * @param string $itemKey + * @param int $mode */ public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, $mode); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php index 76fafdfc6..e8fef1c95 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/ArrayKeyCache.php @@ -62,10 +62,7 @@ class Swift_KeyCache_ArrayKeyCache implements Swift_KeyCache $this->contents[$nsKey][$itemKey] .= $string; break; default: - throw new Swift_SwiftException( - 'Invalid mode ['.$mode.'] used to set nsKey='. - $nsKey.', itemKey='.$itemKey - ); + throw new Swift_SwiftException('Invalid mode ['.$mode.'] used to set nsKey='.$nsKey.', itemKey='.$itemKey); } } @@ -94,10 +91,7 @@ class Swift_KeyCache_ArrayKeyCache implements Swift_KeyCache } break; default: - throw new Swift_SwiftException( - 'Invalid mode ['.$mode.'] used to set nsKey='. - $nsKey.', itemKey='.$itemKey - ); + throw new Swift_SwiftException('Invalid mode ['.$mode.'] used to set nsKey='.$nsKey.', itemKey='.$itemKey); } } @@ -165,7 +159,7 @@ class Swift_KeyCache_ArrayKeyCache implements Swift_KeyCache { $this->prepareCache($nsKey); - return array_key_exists($itemKey, $this->contents[$nsKey]); + return \array_key_exists($itemKey, $this->contents[$nsKey]); } /** @@ -196,7 +190,7 @@ class Swift_KeyCache_ArrayKeyCache implements Swift_KeyCache */ private function prepareCache($nsKey) { - if (!array_key_exists($nsKey, $this->contents)) { + if (!\array_key_exists($nsKey, $this->contents)) { $this->contents[$nsKey] = []; } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php index 7dc2886cc..33b6367cb 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php @@ -80,10 +80,7 @@ class Swift_KeyCache_DiskKeyCache implements Swift_KeyCache $fp = $this->getHandle($nsKey, $itemKey, self::POSITION_END); break; default: - throw new Swift_SwiftException( - 'Invalid mode ['.$mode.'] used to set nsKey='. - $nsKey.', itemKey='.$itemKey - ); + throw new Swift_SwiftException('Invalid mode ['.$mode.'] used to set nsKey='.$nsKey.', itemKey='.$itemKey); break; } fwrite($fp, $string); @@ -112,10 +109,7 @@ class Swift_KeyCache_DiskKeyCache implements Swift_KeyCache $fp = $this->getHandle($nsKey, $itemKey, self::POSITION_END); break; default: - throw new Swift_SwiftException( - 'Invalid mode ['.$mode.'] used to set nsKey='. - $nsKey.', itemKey='.$itemKey - ); + throw new Swift_SwiftException('Invalid mode ['.$mode.'] used to set nsKey='.$nsKey.', itemKey='.$itemKey); break; } while (false !== $bytes = $os->read(8192)) { @@ -224,7 +218,7 @@ class Swift_KeyCache_DiskKeyCache implements Swift_KeyCache */ public function clearAll($nsKey) { - if (array_key_exists($nsKey, $this->keys)) { + if (\array_key_exists($nsKey, $this->keys)) { foreach ($this->keys[$nsKey] as $itemKey => $null) { $this->clearKey($nsKey, $itemKey); } @@ -292,4 +286,9 @@ class Swift_KeyCache_DiskKeyCache implements Swift_KeyCache $this->clearAll($nsKey); } } + + public function __wakeup() + { + $this->keys = []; + } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php index af80bdca6..be2dbba0c 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php @@ -17,8 +17,6 @@ interface Swift_KeyCache_KeyCacheInputStream extends Swift_InputByteStream { /** * Set the KeyCache to wrap. - * - * @param Swift_KeyCache $keyCache */ public function setKeyCache(Swift_KeyCache $keyCache); @@ -38,8 +36,6 @@ interface Swift_KeyCache_KeyCacheInputStream extends Swift_InputByteStream /** * Specify a stream to write through for each write(). - * - * @param Swift_InputByteStream $is */ public function setWriteThroughStream(Swift_InputByteStream $is); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php index ce732af5f..244b5f602 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/LoadBalancedTransport.php @@ -22,7 +22,7 @@ class Swift_LoadBalancedTransport extends Swift_Transport_LoadBalancedTransport */ public function __construct($transports = []) { - call_user_func_array( + \call_user_func_array( [$this, 'Swift_Transport_LoadBalancedTransport::__construct'], Swift_DependencyContainer::getInstance() ->createDependenciesFor('transport.loadbalanced') diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Message.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Message.php index 42b861fc1..819ffc389 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Message.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Message.php @@ -42,7 +42,7 @@ class Swift_Message extends Swift_Mime_SimpleMessage */ public function __construct($subject = null, $body = null, $contentType = null, $charset = null) { - call_user_func_array( + \call_user_func_array( [$this, 'Swift_Mime_SimpleMessage::__construct'], Swift_DependencyContainer::getInstance() ->createDependenciesFor('mime.message') @@ -212,7 +212,7 @@ class Swift_Message extends Swift_Mime_SimpleMessage $this->savedMessage = ['headers' => []]; $this->savedMessage['body'] = $this->getBody(); $this->savedMessage['children'] = $this->getChildren(); - if (count($this->savedMessage['children']) > 0 && '' != $this->getBody()) { + if (\count($this->savedMessage['children']) > 0 && '' != $this->getBody()) { $this->setChildren(array_merge([$this->becomeMimePart()], $this->savedMessage['children'])); $this->setBody(''); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Attachment.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Attachment.php index 917007e46..d994373bd 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Attachment.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Attachment.php @@ -134,7 +134,7 @@ class Swift_Mime_Attachment extends Swift_Mime_SimpleMimeEntity if (!isset($contentType)) { $extension = strtolower(substr($file->getPath(), strrpos($file->getPath(), '.') + 1)); - if (array_key_exists($extension, $this->mimeTypes)) { + if (\array_key_exists($extension, $this->mimeTypes)) { $this->setContentType($this->mimeTypes[$extension]); } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php index 8c4e2266f..2751130d4 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php @@ -46,7 +46,7 @@ class Swift_Mime_ContentEncoder_Base64ContentEncoder extends Swift_Encoder_Base6 $streamTheseBytes = $base64ReadBufferRemainderBytes.$readBytes; } $base64ReadBufferRemainderBytes = null; - $bytesLength = strlen($streamTheseBytes); + $bytesLength = \strlen($streamTheseBytes); if (0 === $bytesLength) { // no data left to encode break; @@ -66,7 +66,7 @@ class Swift_Mime_ContentEncoder_Base64ContentEncoder extends Swift_Encoder_Base6 $encodedTransformed = ''; $thisMaxLineLength = $maxLineLength - $remainder - $firstLineOffset; - while ($thisMaxLineLength < strlen($encoded)) { + while ($thisMaxLineLength < \strlen($encoded)) { $encodedTransformed .= substr($encoded, 0, $thisMaxLineLength)."\r\n"; $firstLineOffset = 0; $encoded = substr($encoded, $thisMaxLineLength); @@ -74,7 +74,7 @@ class Swift_Mime_ContentEncoder_Base64ContentEncoder extends Swift_Encoder_Base6 $remainder = 0; } - if (0 < $remainingLength = strlen($encoded)) { + if (0 < $remainingLength = \strlen($encoded)) { $remainder += $remainingLength; $encodedTransformed .= $encoded; $encoded = null; diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php index 9aae48718..8dfea605f 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php @@ -16,16 +16,16 @@ class Swift_Mime_ContentEncoder_NativeQpContentEncoder implements Swift_Mime_ContentEncoder { /** - * @var null|string + * @var string|null */ private $charset; /** - * @param null|string $charset + * @param string|null $charset */ public function __construct($charset = null) { - $this->charset = $charset ? $charset : 'utf-8'; + $this->charset = $charset ?: 'utf-8'; } /** @@ -51,8 +51,7 @@ class Swift_Mime_ContentEncoder_NativeQpContentEncoder implements Swift_Mime_Con public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0) { if ('utf-8' !== $this->charset) { - throw new RuntimeException( - sprintf('Charset "%s" not supported. NativeQpContentEncoder only supports "utf-8"', $this->charset)); + throw new RuntimeException(sprintf('Charset "%s" not supported. NativeQpContentEncoder only supports "utf-8"', $this->charset)); } $string = ''; @@ -88,8 +87,7 @@ class Swift_Mime_ContentEncoder_NativeQpContentEncoder implements Swift_Mime_Con public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0) { if ('utf-8' !== $this->charset) { - throw new RuntimeException( - sprintf('Charset "%s" not supported. NativeQpContentEncoder only supports "utf-8"', $this->charset)); + throw new RuntimeException(sprintf('Charset "%s" not supported. NativeQpContentEncoder only supports "utf-8"', $this->charset)); } return $this->standardize(quoted_printable_encode($string)); @@ -109,7 +107,7 @@ class Swift_Mime_ContentEncoder_NativeQpContentEncoder implements Swift_Mime_Con // transform =0D=0A to CRLF $string = str_replace(["\t=0D=0A", ' =0D=0A', '=0D=0A'], ["=09\r\n", "=20\r\n", "\r\n"], $string); - switch (ord(substr($string, -1))) { + switch (\ord(substr($string, -1))) { case 0x09: $string = substr_replace($string, '=09', -1); break; diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NullContentEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NullContentEncoder.php index e23507337..6539de77b 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NullContentEncoder.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NullContentEncoder.php @@ -21,7 +21,7 @@ class Swift_Mime_ContentEncoder_NullContentEncoder implements Swift_Mime_Content * * @var string */ - private $_name; + private $name; /** * Creates a new NullContentEncoder with $name (probably 7bit or 8bit). @@ -30,7 +30,7 @@ class Swift_Mime_ContentEncoder_NullContentEncoder implements Swift_Mime_Content */ public function __construct($name) { - $this->_name = $name; + $this->name = $name; } /** @@ -67,7 +67,7 @@ class Swift_Mime_ContentEncoder_NullContentEncoder implements Swift_Mime_Content */ public function getName() { - return $this->_name; + return $this->name; } /** diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php index aa634f54e..72592fc58 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php @@ -37,7 +37,7 @@ class Swift_Mime_ContentEncoder_PlainContentEncoder implements Swift_Mime_Conten * Creates a new PlainContentEncoder with $name (probably 7bit or 8bit). * * @param string $name - * @param bool $canonical If canonicalization transformation should be done. + * @param bool $canonical if canonicalization transformation should be done */ public function __construct($name, $canonical = false) { @@ -84,7 +84,7 @@ class Swift_Mime_ContentEncoder_PlainContentEncoder implements Swift_Mime_Conten $is->write($wrapped); } - if (strlen($leftOver)) { + if (\strlen($leftOver)) { $is->write($leftOver); } } @@ -134,8 +134,8 @@ class Swift_Mime_ContentEncoder_PlainContentEncoder implements Swift_Mime_Conten $chunks = preg_split('/(?<=\s)/', $originalLine); foreach ($chunks as $chunk) { - if (0 != strlen($currentLine) - && strlen($currentLine.$chunk) > $length) { + if (0 != \strlen($currentLine) + && \strlen($currentLine.$chunk) > $length) { $lines[] = ''; $currentLine = &$lines[$lineCount++]; } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php index 84e3d2475..465ffd878 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php @@ -37,7 +37,7 @@ class Swift_Mime_ContentEncoder_QpContentEncoder extends Swift_Encoder_QpEncoder protected function getSafeMapShareId() { - return get_class($this).($this->dotEscape ? '.dotEscape' : ''); + return static::class.($this->dotEscape ? '.dotEscape' : ''); } protected function initSafeMap() @@ -116,7 +116,7 @@ class Swift_Mime_ContentEncoder_QpContentEncoder extends Swift_Encoder_QpEncoder $lineLen = $size - strrpos($enc, '=0D=0A') - 6; } } - if (strlen($currentLine)) { + if (\strlen($currentLine)) { $is->write($prepend.$this->standardize($currentLine)); } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php index 1b06da8c7..f3ece43ae 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php @@ -28,7 +28,7 @@ class Swift_Mime_ContentEncoder_QpContentEncoderProxy implements Swift_Mime_Cont private $nativeEncoder; /** - * @var null|string + * @var string|null */ private $charset; diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php index cc44a6efb..1a952ece1 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php @@ -17,8 +17,6 @@ interface Swift_Mime_EncodingObserver { /** * Notify this observer that the observed entity's ContentEncoder has changed. - * - * @param Swift_Mime_ContentEncoder $encoder */ public function encoderChanged(Swift_Mime_ContentEncoder $encoder); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php index 0eef3e1e7..378c48050 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php @@ -31,7 +31,7 @@ class Swift_Mime_HeaderEncoder_QpHeaderEncoder extends Swift_Encoder_QpEncoder i range(0x61, 0x7A), range(0x41, 0x5A), range(0x30, 0x39), [0x20, 0x21, 0x2A, 0x2B, 0x2D, 0x2F] ) as $byte) { - $this->safeMap[$byte] = chr($byte); + $this->safeMap[$byte] = \chr($byte); } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php index 3a19404a6..22caeb236 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php @@ -216,7 +216,7 @@ abstract class Swift_Mime_Headers_AbstractHeader implements Swift_Mime_Header // ... otherwise it needs encoding // Determine space remaining on line if first line if ($shorten) { - $usedLength = strlen($header->getFieldName().': '); + $usedLength = \strlen($header->getFieldName().': '); } else { $usedLength = 0; } @@ -271,7 +271,7 @@ abstract class Swift_Mime_Headers_AbstractHeader implements Swift_Mime_Header } if (-1 == $usedLength) { - $usedLength = strlen($header->getFieldName().': ') + strlen($value); + $usedLength = \strlen($header->getFieldName().': ') + \strlen($value); } $value .= $this->getTokenAsEncodedWord($token, $usedLength); @@ -313,14 +313,14 @@ abstract class Swift_Mime_Headers_AbstractHeader implements Swift_Mime_Header if ($this->tokenNeedsEncoding($token)) { $encodedToken .= $token; } else { - if (strlen($encodedToken) > 0) { + if (\strlen($encodedToken) > 0) { $tokens[] = $encodedToken; $encodedToken = ''; } $tokens[] = $token; } } - if (strlen($encodedToken)) { + if (\strlen($encodedToken)) { $tokens[] = $encodedToken; } @@ -342,7 +342,7 @@ abstract class Swift_Mime_Headers_AbstractHeader implements Swift_Mime_Header if (isset($this->lang)) { $charsetDecl .= '*'.$this->lang; } - $encodingWrapperLength = strlen( + $encodingWrapperLength = \strlen( '=?'.$charsetDecl.'?'.$this->encoder->getName().'??=' ); @@ -458,8 +458,8 @@ abstract class Swift_Mime_Headers_AbstractHeader implements Swift_Mime_Header foreach ($tokens as $i => $token) { // Line longer than specified maximum or token was just a new line if (("\r\n" == $token) || - ($i > 0 && strlen($currentLine.$token) > $this->lineLength) - && 0 < strlen($currentLine)) { + ($i > 0 && \strlen($currentLine.$token) > $this->lineLength) + && 0 < \strlen($currentLine)) { $headerLines[] = ''; $currentLine = &$headerLines[$lineCount++]; } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php index cadc63f85..4fcdff418 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php @@ -9,6 +9,7 @@ */ use Egulias\EmailValidator\EmailValidator; +use Egulias\EmailValidator\Validation\MessageIDValidation; use Egulias\EmailValidator\Validation\RFCValidation; /** @@ -96,7 +97,7 @@ class Swift_Mime_Headers_IdentificationHeader extends Swift_Mime_Headers_Abstrac */ public function setId($id) { - $this->setIds(is_array($id) ? $id : [$id]); + $this->setIds(\is_array($id) ? $id : [$id]); } /** @@ -108,7 +109,7 @@ class Swift_Mime_Headers_IdentificationHeader extends Swift_Mime_Headers_Abstrac */ public function getId() { - if (count($this->ids) > 0) { + if (\count($this->ids) > 0) { return $this->ids[0]; } } @@ -179,7 +180,9 @@ class Swift_Mime_Headers_IdentificationHeader extends Swift_Mime_Headers_Abstrac */ private function assertValidId($id) { - if (!$this->emailValidator->isValid($id, new RFCValidation())) { + $emailValidation = class_exists(MessageIDValidation::class) ? new MessageIDValidation() : new RFCValidation(); + + if (!$this->emailValidator->isValid($id, $emailValidation)) { throw new Swift_RfcComplianceException('Invalid ID given <'.$id.'>'); } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php index 9f1fe1749..ddd5e8cff 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php @@ -261,7 +261,7 @@ class Swift_Mime_Headers_MailboxHeader extends Swift_Mime_Headers_AbstractHeader $actualMailboxes = []; foreach ($mailboxes as $key => $value) { - if (is_string($key)) { + if (\is_string($key)) { //key is email addr $address = $key; $name = $value; @@ -347,14 +347,12 @@ class Swift_Mime_Headers_MailboxHeader extends Swift_Mime_Headers_AbstractHeader * * @param string $address * - * @throws Swift_RfcComplianceException If invalid. + * @throws Swift_RfcComplianceException if invalid */ private function assertValidAddress($address) { if (!$this->emailValidator->isValid($address, new RFCValidation())) { - throw new Swift_RfcComplianceException( - 'Address in mailbox given ['.$address.'] does not comply with RFC 2822, 3.6.2.' - ); + throw new Swift_RfcComplianceException('Address in mailbox given ['.$address.'] does not comply with RFC 2822, 3.6.2.'); } } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php index 02933c417..47c15e6c0 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php @@ -155,7 +155,7 @@ class Swift_Mime_Headers_ParameterizedHeader extends Swift_Mime_Headers_Unstruct foreach ($this->params as $name => $value) { if (null !== $value) { // Add the semi-colon separator - $tokens[count($tokens) - 1] .= ';'; + $tokens[\count($tokens) - 1] .= ';'; $tokens = array_merge($tokens, $this->generateTokenLines( ' '.$this->createParameter($name, $value) )); @@ -179,7 +179,7 @@ class Swift_Mime_Headers_ParameterizedHeader extends Swift_Mime_Headers_Unstruct $encoded = false; // Allow room for parameter name, indices, "=" and DQUOTEs - $maxValueLength = $this->getMaxLineLength() - strlen($name.'=*N"";') - 1; + $maxValueLength = $this->getMaxLineLength() - \strlen($name.'=*N"";') - 1; $firstLineOffset = 0; // If it's not already a valid parameter value... @@ -189,15 +189,15 @@ class Swift_Mime_Headers_ParameterizedHeader extends Swift_Mime_Headers_Unstruct if (!preg_match('/^[\x00-\x08\x0B\x0C\x0E-\x7F]*$/D', $value)) { $encoded = true; // Allow space for the indices, charset and language - $maxValueLength = $this->getMaxLineLength() - strlen($name.'*N*="";') - 1; - $firstLineOffset = strlen( + $maxValueLength = $this->getMaxLineLength() - \strlen($name.'*N*="";') - 1; + $firstLineOffset = \strlen( $this->getCharset()."'".$this->getLanguage()."'" ); } } // Encode if we need to - if ($encoded || strlen($value) > $maxValueLength) { + if ($encoded || \strlen($value) > $maxValueLength) { if (isset($this->paramEncoder)) { $value = $this->paramEncoder->encodeString( $origValue, $firstLineOffset, $maxValueLength, $this->getCharset() @@ -212,7 +212,7 @@ class Swift_Mime_Headers_ParameterizedHeader extends Swift_Mime_Headers_Unstruct $valueLines = isset($this->paramEncoder) ? explode("\r\n", $value) : [$value]; // Need to add indices - if (count($valueLines) > 1) { + if (\count($valueLines) > 1) { $paramLines = []; foreach ($valueLines as $i => $line) { $paramLines[] = $name.'*'.$i. diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php index d22afbfe9..81b421ee7 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/PathHeader.php @@ -147,9 +147,7 @@ class Swift_Mime_Headers_PathHeader extends Swift_Mime_Headers_AbstractHeader private function assertValidAddress($address) { if (!$this->emailValidator->isValid($address, new RFCValidation())) { - throw new Swift_RfcComplianceException( - 'Address set in PathHeader does not comply with addr-spec of RFC 2822.' - ); + throw new Swift_RfcComplianceException('Address set in PathHeader does not comply with addr-spec of RFC 2822.'); } } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimePart.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimePart.php index 0acfd4e27..fa0726a35 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimePart.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimePart.php @@ -169,7 +169,7 @@ class Swift_Mime_MimePart extends Swift_Mime_SimpleMimeEntity protected function fixHeaders() { parent::fixHeaders(); - if (count($this->getChildren())) { + if (\count($this->getChildren())) { $this->setHeaderParameter('Content-Type', 'charset', null); $this->setHeaderParameter('Content-Type', 'format', null); $this->setHeaderParameter('Content-Type', 'delsp', null); @@ -190,7 +190,7 @@ class Swift_Mime_MimePart extends Swift_Mime_SimpleMimeEntity protected function convertString($string) { $charset = strtolower($this->getCharset()); - if (!in_array($charset, ['utf-8', 'iso-8859-1', 'iso-8859-15', ''])) { + if (!\in_array($charset, ['utf-8', 'iso-8859-1', 'iso-8859-15', ''])) { return mb_convert_encoding($string, $charset, 'utf-8'); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php index 93af99634..b4345f439 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php @@ -68,8 +68,7 @@ class Swift_Mime_SimpleHeaderFactory implements Swift_Mime_CharsetObserver /** * Create a new Date header using $dateTime. * - * @param string $name - * @param DateTimeInterface|null $dateTime + * @param string $name * * @return Swift_Mime_Header */ diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php index a2c319131..3eed5517f 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php @@ -140,16 +140,16 @@ class Swift_Mime_SimpleHeaderSet implements Swift_Mime_CharsetObserver { $lowerName = strtolower($name); - if (!array_key_exists($lowerName, $this->headers)) { + if (!\array_key_exists($lowerName, $this->headers)) { return false; } - if (func_num_args() < 2) { + if (\func_num_args() < 2) { // index was not specified, so we only need to check that there is at least one header value set - return (bool) count($this->headers[$lowerName]); + return (bool) \count($this->headers[$lowerName]); } - return array_key_exists($index, $this->headers[$lowerName]); + return \array_key_exists($index, $this->headers[$lowerName]); } /** @@ -177,13 +177,13 @@ class Swift_Mime_SimpleHeaderSet implements Swift_Mime_CharsetObserver * @param string $name * @param int $index * - * @return Swift_Mime_Header + * @return Swift_Mime_Header|null */ public function get($name, $index = 0) { $name = strtolower($name); - if (func_num_args() < 2) { + if (\func_num_args() < 2) { if ($this->has($name)) { $values = array_values($this->headers[$name]); @@ -215,7 +215,7 @@ class Swift_Mime_SimpleHeaderSet implements Swift_Mime_CharsetObserver } $lowerName = strtolower($name); - if (!array_key_exists($lowerName, $this->headers)) { + if (!\array_key_exists($lowerName, $this->headers)) { return []; } @@ -343,7 +343,7 @@ class Swift_Mime_SimpleHeaderSet implements Swift_Mime_CharsetObserver /** Test if the headers can be sorted */ private function canSort() { - return count($this->order) > 0; + return \count($this->order) > 0; } /** uksort() algorithm for Header ordering */ @@ -351,8 +351,8 @@ class Swift_Mime_SimpleHeaderSet implements Swift_Mime_CharsetObserver { $lowerA = strtolower($a); $lowerB = strtolower($b); - $aPos = array_key_exists($lowerA, $this->order) ? $this->order[$lowerA] : -1; - $bPos = array_key_exists($lowerB, $this->order) ? $this->order[$lowerB] : -1; + $aPos = \array_key_exists($lowerA, $this->order) ? $this->order[$lowerA] : -1; + $bPos = \array_key_exists($lowerB, $this->order) ? $this->order[$lowerB] : -1; if (-1 === $aPos && -1 === $bPos) { // just be sure to be determinist here @@ -371,7 +371,7 @@ class Swift_Mime_SimpleHeaderSet implements Swift_Mime_CharsetObserver /** Test if the given Header is always displayed */ private function isDisplayed(Swift_Mime_Header $header) { - return array_key_exists(strtolower($header->getFieldName()), $this->required); + return \array_key_exists(strtolower($header->getFieldName()), $this->required); } /** Notify all Headers of the new charset */ diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php index ab32f63fe..62da1650a 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php @@ -152,7 +152,7 @@ class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart */ public function setSender($address, $name = null) { - if (!is_array($address) && isset($name)) { + if (!\is_array($address) && isset($name)) { $address = [$address => $name]; } @@ -206,7 +206,7 @@ class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart */ public function setFrom($addresses, $name = null) { - if (!is_array($addresses) && isset($name)) { + if (!\is_array($addresses) && isset($name)) { $addresses = [$addresses => $name]; } @@ -260,7 +260,7 @@ class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart */ public function setReplyTo($addresses, $name = null) { - if (!is_array($addresses) && isset($name)) { + if (!\is_array($addresses) && isset($name)) { $addresses = [$addresses => $name]; } @@ -315,7 +315,7 @@ class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart */ public function setTo($addresses, $name = null) { - if (!is_array($addresses) && isset($name)) { + if (!\is_array($addresses) && isset($name)) { $addresses = [$addresses => $name]; } @@ -367,7 +367,7 @@ class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart */ public function setCc($addresses, $name = null) { - if (!is_array($addresses) && isset($name)) { + if (!\is_array($addresses) && isset($name)) { $addresses = [$addresses => $name]; } @@ -419,7 +419,7 @@ class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart */ public function setBcc($addresses, $name = null) { - if (!is_array($addresses) && isset($name)) { + if (!\is_array($addresses) && isset($name)) { $addresses = [$addresses => $name]; } @@ -568,7 +568,7 @@ class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart */ public function toString() { - if (count($children = $this->getChildren()) > 0 && '' != $this->getBody()) { + if (\count($children = $this->getChildren()) > 0 && '' != $this->getBody()) { $this->setChildren(array_merge([$this->becomeMimePart()], $children)); $string = parent::toString(); $this->setChildren($children); @@ -596,7 +596,7 @@ class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart */ public function toByteStream(Swift_InputByteStream $is) { - if (count($children = $this->getChildren()) > 0 && '' != $this->getBody()) { + if (\count($children = $this->getChildren()) > 0 && '' != $this->getBody()) { $this->setChildren(array_merge([$this->becomeMimePart()], $children)); parent::toByteStream($is); $this->setChildren($children); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php index 63dda3d6e..fa18aa8da 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php @@ -634,7 +634,7 @@ class Swift_Mime_SimpleMimeEntity implements Swift_Mime_CharsetObserver, Swift_M */ protected function fixHeaders() { - if (count($this->immediateChildren)) { + if (\count($this->immediateChildren)) { $this->setHeaderParameter('Content-Type', 'boundary', $this->getBoundary() ); @@ -778,7 +778,7 @@ class Swift_Mime_SimpleMimeEntity implements Swift_Mime_CharsetObserver, Swift_M $sorted = []; foreach ($this->immediateChildren as $child) { $type = $child->getContentType(); - $level = array_key_exists($type, $this->alternativePartOrder) ? $this->alternativePartOrder[$type] : max($this->alternativePartOrder) + 1; + $level = \array_key_exists($type, $this->alternativePartOrder) ? $this->alternativePartOrder[$type] : max($this->alternativePartOrder) + 1; if (empty($sorted[$level])) { $sorted[$level] = []; @@ -817,4 +817,10 @@ class Swift_Mime_SimpleMimeEntity implements Swift_Mime_CharsetObserver, Swift_M } $this->setChildren($children); } + + public function __wakeup() + { + $this->cacheKey = bin2hex(random_bytes(16)); // set 32 hex values + $this->cache = new Swift_KeyCache_ArrayKeyCache(new Swift_KeyCache_SimpleKeyCacheInputStream()); + } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MimePart.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MimePart.php index 14f84324a..ea97619ad 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MimePart.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MimePart.php @@ -26,7 +26,7 @@ class Swift_MimePart extends Swift_Mime_MimePart */ public function __construct($body = null, $contentType = null, $charset = null) { - call_user_func_array( + \call_user_func_array( [$this, 'Swift_Mime_MimePart::__construct'], Swift_DependencyContainer::getInstance() ->createDependenciesFor('mime.part') diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/NullTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/NullTransport.php index eefb9a6f7..e44b7af98 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/NullTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/NullTransport.php @@ -17,7 +17,7 @@ class Swift_NullTransport extends Swift_Transport_NullTransport { public function __construct() { - call_user_func_array( + \call_user_func_array( [$this, 'Swift_Transport_NullTransport::__construct'], Swift_DependencyContainer::getInstance() ->createDependenciesFor('transport.null') diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php index f7a24dd00..36451f44f 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/BandwidthMonitorPlugin.php @@ -54,7 +54,7 @@ class Swift_Plugins_BandwidthMonitorPlugin implements Swift_Events_SendListener, public function commandSent(Swift_Events_CommandEvent $evt) { $command = $evt->getCommand(); - $this->out += strlen($command); + $this->out += \strlen($command); } /** @@ -63,7 +63,7 @@ class Swift_Plugins_BandwidthMonitorPlugin implements Swift_Events_SendListener, public function responseReceived(Swift_Events_ResponseEvent $evt) { $response = $evt->getResponse(); - $this->in += strlen($response); + $this->in += \strlen($response); } /** @@ -73,7 +73,7 @@ class Swift_Plugins_BandwidthMonitorPlugin implements Swift_Events_SendListener, */ public function write($bytes) { - $this->out += strlen($bytes); + $this->out += \strlen($bytes); foreach ($this->mirrors as $stream) { $stream->write($bytes); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php index c4b6ee127..93124c9a5 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/DecoratorPlugin.php @@ -96,20 +96,20 @@ class Swift_Plugins_DecoratorPlugin implements Swift_Events_SendListener, Swift_ foreach ($message->getHeaders()->getAll() as $header) { $body = $header->getFieldBodyModel(); $count = 0; - if (is_array($body)) { + if (\is_array($body)) { $bodyReplaced = []; foreach ($body as $key => $value) { $count1 = 0; $count2 = 0; - $key = is_string($key) ? str_replace($search, $replace, $key, $count1) : $key; - $value = is_string($value) ? str_replace($search, $replace, $value, $count2) : $value; + $key = \is_string($key) ? str_replace($search, $replace, $key, $count1) : $key; + $value = \is_string($value) ? str_replace($search, $replace, $value, $count2) : $value; $bodyReplaced[$key] = $value; if (!$count && ($count1 || $count2)) { $count = 1; } } - } elseif (is_string($body)) { + } elseif (\is_string($body)) { $bodyReplaced = str_replace($search, $replace, $body, $count); } @@ -178,7 +178,7 @@ class Swift_Plugins_DecoratorPlugin implements Swift_Events_SendListener, Swift_ } if (!empty($this->originalHeaders)) { foreach ($message->getHeaders()->getAll() as $header) { - if (array_key_exists($header->getFieldName(), $this->originalHeaders)) { + if (\array_key_exists($header->getFieldName(), $this->originalHeaders)) { $header->setFieldBodyModel($this->originalHeaders[$header->getFieldName()]); } } @@ -188,7 +188,7 @@ class Swift_Plugins_DecoratorPlugin implements Swift_Events_SendListener, Swift_ $children = (array) $message->getChildren(); foreach ($children as $child) { $id = $child->getId(); - if (array_key_exists($id, $this->originalChildBodies)) { + if (\array_key_exists($id, $this->originalChildBodies)) { $child->setBody($this->originalChildBodies[$id]); } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php index c70a03824..e183749b7 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/LoggerPlugin.php @@ -77,7 +77,7 @@ class Swift_Plugins_LoggerPlugin implements Swift_Events_CommandListener, Swift_ */ public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt) { - $transportName = get_class($evt->getSource()); + $transportName = \get_class($evt->getSource()); $this->logger->add(sprintf('++ Starting %s', $transportName)); } @@ -86,7 +86,7 @@ class Swift_Plugins_LoggerPlugin implements Swift_Events_CommandListener, Swift_ */ public function transportStarted(Swift_Events_TransportChangeEvent $evt) { - $transportName = get_class($evt->getSource()); + $transportName = \get_class($evt->getSource()); $this->logger->add(sprintf('++ %s started', $transportName)); } @@ -95,7 +95,7 @@ class Swift_Plugins_LoggerPlugin implements Swift_Events_CommandListener, Swift_ */ public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt) { - $transportName = get_class($evt->getSource()); + $transportName = \get_class($evt->getSource()); $this->logger->add(sprintf('++ Stopping %s', $transportName)); } @@ -104,7 +104,7 @@ class Swift_Plugins_LoggerPlugin implements Swift_Events_CommandListener, Swift_ */ public function transportStopped(Swift_Events_TransportChangeEvent $evt) { - $transportName = get_class($evt->getSource()); + $transportName = \get_class($evt->getSource()); $this->logger->add(sprintf('++ %s stopped', $transportName)); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php index b00bcaa11..6f595adaa 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Loggers/ArrayLogger.php @@ -47,7 +47,7 @@ class Swift_Plugins_Loggers_ArrayLogger implements Swift_Plugins_Logger public function add($entry) { $this->log[] = $entry; - while (count($this->log) > $this->size) { + while (\count($this->log) > $this->size) { array_shift($this->log); } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php index 3b4de80ec..39c48ed18 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/MessageLogger.php @@ -42,7 +42,7 @@ class Swift_Plugins_MessageLogger implements Swift_Events_SendListener */ public function countMessages() { - return count($this->messages); + return \count($this->messages); } /** diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php index 1d5da1c64..1ecfce050 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/PopBeforeSmtpPlugin.php @@ -132,16 +132,12 @@ class Swift_Plugins_PopBeforeSmtpPlugin implements Swift_Events_TransportChangeL if (!isset($this->socket)) { if (!$socket = fsockopen( $this->getHostString(), $this->port, $errno, $errstr, $this->timeout)) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to connect to POP3 host [%s]: %s', $this->host, $errstr) - ); + throw new Swift_Plugins_Pop_Pop3Exception(sprintf('Failed to connect to POP3 host [%s]: %s', $this->host, $errstr)); } $this->socket = $socket; if (false === $greeting = fgets($this->socket)) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to connect to POP3 host [%s]', trim($greeting)) - ); + throw new Swift_Plugins_Pop_Pop3Exception(sprintf('Failed to connect to POP3 host [%s]', trim($greeting))); } $this->assertOk($greeting); @@ -164,9 +160,7 @@ class Swift_Plugins_PopBeforeSmtpPlugin implements Swift_Events_TransportChangeL } else { $this->command("QUIT\r\n"); if (!fclose($this->socket)) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('POP3 host [%s] connection could not be stopped', $this->host) - ); + throw new Swift_Plugins_Pop_Pop3Exception(sprintf('POP3 host [%s] connection could not be stopped', $this->host)); } $this->socket = null; } @@ -211,15 +205,11 @@ class Swift_Plugins_PopBeforeSmtpPlugin implements Swift_Events_TransportChangeL private function command($command) { if (!fwrite($this->socket, $command)) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to write command [%s] to POP3 host', trim($command)) - ); + throw new Swift_Plugins_Pop_Pop3Exception(sprintf('Failed to write command [%s] to POP3 host', trim($command))); } if (false === $response = fgets($this->socket)) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('Failed to read from POP3 host after command [%s]', trim($command)) - ); + throw new Swift_Plugins_Pop_Pop3Exception(sprintf('Failed to read from POP3 host after command [%s]', trim($command))); } $this->assertOk($response); @@ -230,9 +220,7 @@ class Swift_Plugins_PopBeforeSmtpPlugin implements Swift_Events_TransportChangeL private function assertOk($response) { if ('+OK' != substr($response, 0, 3)) { - throw new Swift_Plugins_Pop_Pop3Exception( - sprintf('POP3 command failed [%s]', trim($response)) - ); + throw new Swift_Plugins_Pop_Pop3Exception(sprintf('POP3 command failed [%s]', trim($response))); } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php index b0cb519e0..f7373b242 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/RedirectingPlugin.php @@ -112,7 +112,7 @@ class Swift_Plugins_RedirectingPlugin implements Swift_Events_SendListener } foreach ((array) $this->recipient as $recipient) { - if (!array_key_exists($recipient, $to)) { + if (!\array_key_exists($recipient, $to)) { $message->addTo($recipient); } } @@ -155,7 +155,7 @@ class Swift_Plugins_RedirectingPlugin implements Swift_Events_SendListener */ protected function isWhitelisted($recipient) { - if (in_array($recipient, (array) $this->recipient)) { + if (\in_array($recipient, (array) $this->recipient)) { return true; } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporter.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporter.php index 3a2b6657c..b88183397 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporter.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/Reporter.php @@ -24,9 +24,8 @@ interface Swift_Plugins_Reporter /** * Notifies this ReportNotifier that $address failed or succeeded. * - * @param Swift_Mime_SimpleMessage $message - * @param string $address - * @param int $result from {@link RESULT_PASS, RESULT_FAIL} + * @param string $address + * @param int $result from {@link RESULT_PASS, RESULT_FAIL} */ public function notify(Swift_Mime_SimpleMessage $message, $address, $result); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php index ae070eb64..c4a016520 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Plugins/ReporterPlugin.php @@ -45,13 +45,13 @@ class Swift_Plugins_ReporterPlugin implements Swift_Events_SendListener $message = $evt->getMessage(); $failures = array_flip($evt->getFailedRecipients()); foreach ((array) $message->getTo() as $address => $null) { - $this->reporter->notify($message, $address, (array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS)); + $this->reporter->notify($message, $address, (\array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS)); } foreach ((array) $message->getCc() as $address => $null) { - $this->reporter->notify($message, $address, (array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS)); + $this->reporter->notify($message, $address, (\array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS)); } foreach ((array) $message->getBcc() as $address => $null) { - $this->reporter->notify($message, $address, (array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS)); + $this->reporter->notify($message, $address, (\array_key_exists($address, $failures) ? Swift_Plugins_Reporter::RESULT_FAIL : Swift_Plugins_Reporter::RESULT_PASS)); } } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SendmailTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SendmailTransport.php index 2aa7e3261..3c756436c 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SendmailTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SendmailTransport.php @@ -22,7 +22,7 @@ class Swift_SendmailTransport extends Swift_Transport_SendmailTransport */ public function __construct($command = '/usr/sbin/sendmail -bs') { - call_user_func_array( + \call_user_func_array( [$this, 'Swift_Transport_SendmailTransport::__construct'], Swift_DependencyContainer::getInstance() ->createDependenciesFor('transport.sendmail') diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/BodySigner.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/BodySigner.php index 8e66e18f4..b25c427af 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/BodySigner.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/BodySigner.php @@ -18,8 +18,6 @@ interface Swift_Signers_BodySigner extends Swift_Signer /** * Change the Swift_Signed_Message to apply the singing. * - * @param Swift_Message $message - * * @return self */ public function signMessage(Swift_Message $message); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/DKIMSigner.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/DKIMSigner.php index 7f1bf4a5f..9a26abd35 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/DKIMSigner.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/DKIMSigner.php @@ -295,7 +295,7 @@ class Swift_Signers_DKIMSigner implements Swift_Signers_HeaderSigner break; case 'rsa-sha256': $this->hashAlgorithm = 'rsa-sha256'; - if (!defined('OPENSSL_ALGO_SHA256')) { + if (!\defined('OPENSSL_ALGO_SHA256')) { throw new Swift_SwiftException('Unable to set sha256 as it is not supported by OpenSSL.'); } break; @@ -574,7 +574,7 @@ class Swift_Signers_DKIMSigner implements Swift_Signers_HeaderSigner protected function canonicalizeBody($string) { - $len = strlen($string); + $len = \strlen($string); $canon = ''; $method = ('relaxed' == $this->bodyCanon); for ($i = 0; $i < $len; ++$i) { @@ -629,7 +629,7 @@ class Swift_Signers_DKIMSigner implements Swift_Signers_HeaderSigner protected function endOfBody() { // Add trailing Line return if last line is non empty - if (strlen($this->bodyCanonLine) > 0) { + if (\strlen($this->bodyCanonLine) > 0) { $this->addToBodyHash("\r\n"); } $this->bodyHash = hash_final($this->bodyHashHandler, true); @@ -637,7 +637,7 @@ class Swift_Signers_DKIMSigner implements Swift_Signers_HeaderSigner private function addToBodyHash($string) { - $len = strlen($string); + $len = \strlen($string); if ($len > ($new_len = ($this->maxLen - $this->bodyLen))) { $string = substr($string, 0, $new_len); $len = $new_len; diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/DomainKeySigner.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/DomainKeySigner.php index a24d2032d..8833765b3 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/DomainKeySigner.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/DomainKeySigner.php @@ -412,7 +412,7 @@ class Swift_Signers_DomainKeySigner implements Swift_Signers_HeaderSigner protected function canonicalizeBody($string) { - $len = strlen($string); + $len = \strlen($string); $canon = ''; $nofws = ('nofws' == $this->canon); for ($i = 0; $i < $len; ++$i) { @@ -462,7 +462,7 @@ class Swift_Signers_DomainKeySigner implements Swift_Signers_HeaderSigner protected function endOfBody() { - if (strlen($this->bodyCanonLine) > 0) { + if (\strlen($this->bodyCanonLine) > 0) { $this->addToHash("\r\n"); } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/HeaderSigner.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/HeaderSigner.php index 6104e34f3..6f5c20923 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/HeaderSigner.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/HeaderSigner.php @@ -41,8 +41,6 @@ interface Swift_Signers_HeaderSigner extends Swift_Signer, Swift_InputByteStream /** * Give the headers already given. * - * @param Swift_Mime_SimpleHeaderSet $headers - * * @return self */ public function setHeaders(Swift_Mime_SimpleHeaderSet $headers); @@ -50,8 +48,6 @@ interface Swift_Signers_HeaderSigner extends Swift_Signer, Swift_InputByteStream /** * Add the header(s) to the headerSet. * - * @param Swift_Mime_SimpleHeaderSet $headers - * * @return self */ public function addSignature(Swift_Mime_SimpleHeaderSet $headers); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/OpenDKIMSigner.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/OpenDKIMSigner.php index 7b50c51d4..6d7b589cb 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/OpenDKIMSigner.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/OpenDKIMSigner.php @@ -31,7 +31,7 @@ class Swift_Signers_OpenDKIMSigner extends Swift_Signers_DKIMSigner public function __construct($privateKey, $domainName, $selector) { - if (!extension_loaded('opendkim')) { + if (!\extension_loaded('opendkim')) { throw new Swift_SwiftException('php-opendkim extension not found'); } @@ -44,7 +44,7 @@ class Swift_Signers_OpenDKIMSigner extends Swift_Signers_DKIMSigner { $header = new Swift_Mime_Headers_OpenDKIMHeader('DKIM-Signature'); $headerVal = $this->dkimHandler->getSignatureHeader(); - if (false === $headerVal || is_int($headerVal)) { + if (false === $headerVal || \is_int($headerVal)) { throw new Swift_SwiftException('OpenDKIM Error: '.$this->dkimHandler->getError()); } $header->setValue($headerVal); @@ -176,7 +176,7 @@ class Swift_Signers_OpenDKIMSigner extends Swift_Signers_DKIMSigner } } $this->dropFirstLF = false; - if (strlen($string)) { + if (\strlen($string)) { $this->dkimHandler->body($string); } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/SMimeSigner.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/SMimeSigner.php index 84c53edb5..30f3cbdf6 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/SMimeSigner.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Signers/SMimeSigner.php @@ -80,7 +80,7 @@ class Swift_Signers_SMimeSigner implements Swift_Signers_BodySigner $this->signCertificate = 'file://'.str_replace('\\', '/', realpath($certificate)); if (null !== $privateKey) { - if (is_array($privateKey)) { + if (\is_array($privateKey)) { $this->signPrivateKey = $privateKey; $this->signPrivateKey[0] = 'file://'.str_replace('\\', '/', realpath($privateKey[0])); } else { @@ -107,7 +107,7 @@ class Swift_Signers_SMimeSigner implements Swift_Signers_BodySigner */ public function setEncryptCertificate($recipientCerts, $cipher = null) { - if (is_array($recipientCerts)) { + if (\is_array($recipientCerts)) { $this->encryptCert = []; foreach ($recipientCerts as $cert) { @@ -509,7 +509,7 @@ class Swift_Signers_SMimeSigner implements Swift_Signers_BodySigner $bodyStream = new Swift_ByteStream_TemporaryFileByteStream(); // Skip the header and separator and point to the body - $emailStream->setReadPointer($headersPosEnd + strlen($headerBodySeparator)); + $emailStream->setReadPointer($headersPosEnd + \strlen($headerBodySeparator)); while (false !== ($buffer = $emailStream->read($bufferLength))) { $bodyStream->write($buffer); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php index e241e6786..ff4d7faae 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php @@ -25,11 +25,14 @@ class Swift_SmtpTransport extends Swift_Transport_EsmtpTransport /** * @param string $host * @param int $port - * @param string $encryption + * @param string|null $encryption SMTP encryption mode: + * - null for plain SMTP (no encryption), + * - 'tls' for SMTP with STARTTLS (best effort encryption), + * - 'ssl' for SMTPS = SMTP over TLS (always encrypted). */ public function __construct($host = 'localhost', $port = 25, $encryption = null) { - call_user_func_array( + \call_user_func_array( [$this, 'Swift_Transport_EsmtpTransport::__construct'], Swift_DependencyContainer::getInstance() ->createDependenciesFor('transport.smtp') diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SpoolTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SpoolTransport.php index 4b30f04ed..c08e0fb17 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SpoolTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SpoolTransport.php @@ -25,7 +25,7 @@ class Swift_SpoolTransport extends Swift_Transport_SpoolTransport $arguments[] = $spool; - call_user_func_array( + \call_user_func_array( [$this, 'Swift_Transport_SpoolTransport::__construct'], $arguments ); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php index c3b7675dd..7e5ddf1b7 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php @@ -49,11 +49,11 @@ class Swift_StreamFilters_ByteArrayReplacementFilter implements Swift_StreamFilt $last_size = $size = 0; foreach ($search as $i => $search_element) { if (null !== $tree) { - $tree[-1] = min(count($replace) - 1, $i - 1); + $tree[-1] = min(\count($replace) - 1, $i - 1); $tree[-2] = $last_size; } $tree = &$this->tree; - if (is_array($search_element)) { + if (\is_array($search_element)) { foreach ($search_element as $k => $char) { $this->index[$char] = true; if (!isset($tree[$char])) { @@ -74,19 +74,19 @@ class Swift_StreamFilters_ByteArrayReplacementFilter implements Swift_StreamFilt } } if (null !== $i) { - $tree[-1] = min(count($replace) - 1, $i); + $tree[-1] = min(\count($replace) - 1, $i); $tree[-2] = $last_size; $this->treeMaxLen = $size; } foreach ($replace as $rep) { - if (!is_array($rep)) { + if (!\is_array($rep)) { $rep = [$rep]; } $this->replace[] = $rep; } - for ($i = count($this->replace) - 1; $i >= 0; --$i) { + for ($i = \count($this->replace) - 1; $i >= 0; --$i) { $this->replace[$i] = $rep = $this->filter($this->replace[$i], $i); - $this->repSize[$i] = count($rep); + $this->repSize[$i] = \count($rep); } } @@ -119,7 +119,7 @@ class Swift_StreamFilters_ByteArrayReplacementFilter implements Swift_StreamFilt } $newBuffer = []; - $buf_size = count($buffer); + $buf_size = \count($buffer); $last_size = 0; for ($i = 0; $i < $buf_size; ++$i) { $search_pos = $this->tree; diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport.php index 0951f35e7..bc324e868 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport.php @@ -63,8 +63,7 @@ interface Swift_Transport * * This is the responsibility of the send method to start the transport if needed. * - * @param Swift_Mime_SimpleMessage $message - * @param string[] $failedRecipients An array of failures by-reference + * @param string[] $failedRecipients An array of failures by-reference * * @return int */ @@ -72,8 +71,6 @@ interface Swift_Transport /** * Register a plugin in the Transport. - * - * @param Swift_Events_EventListener $plugin */ public function registerPlugin(Swift_Events_EventListener $plugin); } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php index 18c8d9b90..d2dbd7a66 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php @@ -197,20 +197,19 @@ abstract class Swift_Transport_AbstractSmtpTransport implements Swift_Transport $to = (array) $message->getTo(); $cc = (array) $message->getCc(); - $tos = array_merge($to, $cc); $bcc = (array) $message->getBcc(); + $tos = array_merge($to, $cc, $bcc); $message->setBcc([]); try { $sent += $this->sendTo($message, $reversePath, $tos, $failedRecipients); - $sent += $this->sendBcc($message, $reversePath, $bcc, $failedRecipients); } finally { $message->setBcc($bcc); } if ($evt) { - if ($sent == count($to) + count($cc) + count($bcc)) { + if ($sent == \count($to) + \count($cc) + \count($bcc)) { $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS); } elseif ($sent > 0) { $evt->setResult(Swift_Events_SendEvent::RESULT_TENTATIVE); @@ -318,7 +317,7 @@ abstract class Swift_Transport_AbstractSmtpTransport implements Swift_Transport * @param int[] $codes * @param string[] $failures An array of failures by-reference * @param bool $pipeline Do not wait for response - * @param string $address The address, if command is RCPT TO. + * @param string $address the address, if command is RCPT TO * * @return string|null The server response, or null if pipelining is enabled */ @@ -331,20 +330,23 @@ abstract class Swift_Transport_AbstractSmtpTransport implements Swift_Transport } $this->pipeline[] = [$command, $seq, $codes, $address]; + if ($pipeline && $this->pipelining) { - $response = null; - } else { - while ($this->pipeline) { - list($command, $seq, $codes, $address) = array_shift($this->pipeline); - $response = $this->getFullResponse($seq); - try { - $this->assertResponseCode($response, $codes); - } catch (Swift_TransportException $e) { - if ($this->pipeline && $address) { - $failures[] = $address; - } else { - $this->throwException($e); - } + return null; + } + + $response = null; + + while ($this->pipeline) { + list($command, $seq, $codes, $address) = array_shift($this->pipeline); + $response = $this->getFullResponse($seq); + try { + $this->assertResponseCode($response, $codes); + } catch (Swift_TransportException $e) { + if ($this->pipeline && $address) { + $failures[] = $address; + } else { + $this->throwException($e); } } } @@ -446,7 +448,7 @@ abstract class Swift_Transport_AbstractSmtpTransport implements Swift_Transport } list($code) = sscanf($response, '%3d'); - $valid = (empty($wanted) || in_array($code, $wanted)); + $valid = (empty($wanted) || \in_array($code, $wanted)); if ($evt = $this->eventDispatcher->createResponseEvent($this, $response, $valid)) { @@ -493,9 +495,9 @@ abstract class Swift_Transport_AbstractSmtpTransport implements Swift_Transport } if (0 != $sent) { - $sent += count($failedRecipients); + $sent += \count($failedRecipients); $this->doDataCommand($failedRecipients); - $sent -= count($failedRecipients); + $sent -= \count($failedRecipients); $this->streamMessage($message); } else { @@ -516,20 +518,6 @@ abstract class Swift_Transport_AbstractSmtpTransport implements Swift_Transport $failedRecipients); } - /** Send a message to all Bcc: recipients */ - private function sendBcc(Swift_Mime_SimpleMessage $message, $reversePath, array $bcc, array &$failedRecipients) - { - $sent = 0; - foreach ($bcc as $forwardPath => $name) { - $message->setBcc([$forwardPath => $name]); - $sent += $this->doMailTransaction( - $message, $reversePath, [$forwardPath], $failedRecipients - ); - } - - return $sent; - } - /** * Destructor. */ @@ -540,4 +528,14 @@ abstract class Swift_Transport_AbstractSmtpTransport implements Swift_Transport } catch (Exception $e) { } } + + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php index 51dc7f563..e7ccf6dba 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php @@ -56,16 +56,16 @@ class Swift_Transport_Esmtp_Auth_CramMd5Authenticator implements Swift_Transport */ private function getResponse($secret, $challenge) { - if (strlen($secret) > 64) { + if (\strlen($secret) > 64) { $secret = pack('H32', md5($secret)); } - if (strlen($secret) < 64) { - $secret = str_pad($secret, 64, chr(0)); + if (\strlen($secret) < 64) { + $secret = str_pad($secret, 64, \chr(0)); } - $k_ipad = substr($secret, 0, 64) ^ str_repeat(chr(0x36), 64); - $k_opad = substr($secret, 0, 64) ^ str_repeat(chr(0x5C), 64); + $k_ipad = substr($secret, 0, 64) ^ str_repeat(\chr(0x36), 64); + $k_opad = substr($secret, 0, 64) ^ str_repeat(\chr(0x5C), 64); $inner = pack('H32', md5($k_ipad.$challenge)); $digest = md5($k_opad.$inner); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php index 90081f8e6..21c070e34 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php @@ -37,11 +37,11 @@ class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Es */ public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password) { - if (!function_exists('openssl_encrypt')) { + if (!\function_exists('openssl_encrypt')) { throw new LogicException('The OpenSSL extension must be enabled to use the NTLM authenticator.'); } - if (!function_exists('bcmul')) { + if (!\function_exists('bcmul')) { throw new LogicException('The BCMath functions must be enabled to use the NTLM authenticator.'); } @@ -51,8 +51,8 @@ class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Es $response = base64_decode(substr(trim($this->sendMessage1($agent)), 4)); // extra parameters for our unit cases - $timestamp = func_num_args() > 3 ? func_get_arg(3) : $this->getCorrectTimestamp(bcmul(microtime(true), '1000')); - $client = func_num_args() > 4 ? func_get_arg(4) : random_bytes(8); + $timestamp = \func_num_args() > 3 ? func_get_arg(3) : $this->getCorrectTimestamp(bcmul(microtime(true), '1000')); + $client = \func_num_args() > 4 ? func_get_arg(4) : random_bytes(8); // Message 3 response $this->sendMessage3($response, $username, $password, $timestamp, $client, $agent); @@ -68,20 +68,20 @@ class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Es protected function si2bin($si, $bits = 32) { $bin = null; - if ($si >= -pow(2, $bits - 1) && ($si <= pow(2, $bits - 1))) { + if ($si >= -2 ** ($bits - 1) && ($si <= 2 ** ($bits - 1))) { // positive or zero if ($si >= 0) { $bin = base_convert($si, 10, 2); // pad to $bits bit - $bin_length = strlen($bin); + $bin_length = \strlen($bin); if ($bin_length < $bits) { $bin = str_repeat('0', $bits - $bin_length).$bin; } } else { // negative - $si = -$si - pow(2, $bits); + $si = -$si - 2 ** $bits; $bin = base_convert($si, 10, 2); - $bin_length = strlen($bin); + $bin_length = \strlen($bin); if ($bin_length > $bits) { $bin = str_repeat('1', $bits - $bin_length).$bin; } @@ -147,7 +147,7 @@ class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Es // remove terminatorByte cause it's always the same $block = substr($block, 0, -8); - $length = strlen($block); + $length = \strlen($block); $offset = 0; $data = []; while ($offset < $length) { @@ -157,7 +157,7 @@ class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Es $offset += $blockLength * 2; } - if (3 == count($data)) { + if (3 == \count($data)) { $data[] = $data[2]; $data[2] = ''; } @@ -364,7 +364,7 @@ class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Es $binary = $this->si2bin($time, 64); // create 64 bit binary string $timestamp = ''; for ($i = 0; $i < 8; ++$i) { - $timestamp .= chr(bindec(substr($binary, -(($i + 1) * 8), 8))); + $timestamp .= \chr(bindec(substr($binary, -(($i + 1) * 8), 8))); } return $timestamp; @@ -385,7 +385,7 @@ class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Es { $lmPass = '00'; // by default 00 // if $password > 15 than we can't use this method - if (strlen($password) <= 15) { + if (\strlen($password) <= 15) { $ntlmHash = $this->md4Encrypt($password); $ntml2Hash = $this->md5Encrypt($ntlmHash, $this->convertTo16bit(strtoupper($username).$domain)); @@ -426,13 +426,13 @@ class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Es protected function createDesKey($key) { $material = [bin2hex($key[0])]; - $len = strlen($key); + $len = \strlen($key); for ($i = 1; $i < $len; ++$i) { list($high, $low) = str_split(bin2hex($key[$i])); - $v = $this->castToByte(ord($key[$i - 1]) << (7 + 1 - $i) | $this->uRShift(hexdec(dechex(hexdec($high) & 0xf).dechex(hexdec($low) & 0xf)), $i)); + $v = $this->castToByte(\ord($key[$i - 1]) << (7 + 1 - $i) | $this->uRShift(hexdec(dechex(hexdec($high) & 0xf).dechex(hexdec($low) & 0xf)), $i)); $material[] = str_pad(substr(dechex($v), -2), 2, '0', STR_PAD_LEFT); // cast to byte } - $material[] = str_pad(substr(dechex($this->castToByte(ord($key[6]) << 1)), -2), 2, '0'); + $material[] = str_pad(substr(dechex($this->castToByte(\ord($key[6]) << 1)), -2), 2, '0'); // odd parity foreach ($material as $k => $v) { @@ -465,7 +465,7 @@ class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Es */ protected function createSecurityBuffer($value, $offset, $is16 = false) { - $length = strlen(bin2hex($value)); + $length = \strlen(bin2hex($value)); $length = $is16 ? $length / 2 : $length; $length = $this->createByte(str_pad(dechex($length), 2, '0', STR_PAD_LEFT), 2); @@ -563,7 +563,7 @@ class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Es protected function md5Encrypt($key, $msg) { $blocksize = 64; - if (strlen($key) > $blocksize) { + if (\strlen($key) > $blocksize) { $key = pack('H*', md5($key)); } @@ -587,7 +587,7 @@ class Swift_Transport_Esmtp_Auth_NTLMAuthenticator implements Swift_Transport_Es { $input = $this->convertTo16bit($input); - return function_exists('hash') ? hex2bin(hash('md4', $input)) : mhash(MHASH_MD4, $input); + return \function_exists('hash') ? hex2bin(hash('md4', $input)) : mhash(MHASH_MD4, $input); } /** diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php index 1ff961cc3..41d0a50a8 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php @@ -31,7 +31,7 @@ class Swift_Transport_Esmtp_Auth_PlainAuthenticator implements Swift_Transport_E public function authenticate(Swift_Transport_SmtpAgent $agent, $username, $password) { try { - $message = base64_encode($username.chr(0).$username.chr(0).$password); + $message = base64_encode($username.\chr(0).$username.\chr(0).$password); $agent->executeCommand(sprintf("AUTH PLAIN %s\r\n", $message), [235]); return true; diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php index 37334208a..dd559132b 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php @@ -171,7 +171,7 @@ class Swift_Transport_Esmtp_AuthHandler implements Swift_Transport_EsmtpHandler $count = 0; $errors = []; foreach ($this->getAuthenticatorsForAgent() as $authenticator) { - if (in_array(strtolower($authenticator->getAuthKeyword()), array_map('strtolower', $this->esmtpParams))) { + if (\in_array(strtolower($authenticator->getAuthKeyword()), array_map('strtolower', $this->esmtpParams))) { ++$count; try { if ($authenticator->authenticate($agent, $this->username, $this->password)) { diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php index cadfdc651..f692a6fe4 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php @@ -25,9 +25,8 @@ interface Swift_Transport_Esmtp_Authenticator /** * Try to authenticate the user with $username and $password. * - * @param Swift_Transport_SmtpAgent $agent - * @param string $username - * @param string $password + * @param string $username + * @param string $password * * @return bool true if authentication worked (returning false is deprecated, throw a Swift_TransportException instead) * diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php index d1f1c2cf7..bce0cdd42 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php @@ -235,7 +235,7 @@ class Swift_Transport_EsmtpTransport extends Swift_Transport_AbstractSmtpTranspo * Returns whether SMTP pipelining is enabled. * * @return bool|null a boolean if pipelining is explicitly enabled or disabled, - * or null if support is auto-detected. + * or null if support is auto-detected */ public function getPipelining() { @@ -284,7 +284,7 @@ class Swift_Transport_EsmtpTransport extends Swift_Transport_AbstractSmtpTranspo * @param int[] $codes * @param string[] $failures An array of failures by-reference * @param bool $pipeline Do not wait for response - * @param string $address The address, if command is RCPT TO. + * @param string $address the address, if command is RCPT TO * * @return string|null The server response, or null if pipelining is enabled */ @@ -309,10 +309,10 @@ class Swift_Transport_EsmtpTransport extends Swift_Transport_AbstractSmtpTranspo public function __call($method, $args) { foreach ($this->handlers as $handler) { - if (in_array(strtolower($method), + if (\in_array(strtolower($method), array_map('strtolower', (array) $handler->exposeMixinMethods()) )) { - $return = call_user_func_array([$handler, $method], $args); + $return = \call_user_func_array([$handler, $method], $args); // Allow fluid method calls if (null === $return && 'set' == substr($method, 0, 3)) { return $this; @@ -425,7 +425,7 @@ class Swift_Transport_EsmtpTransport extends Swift_Transport_AbstractSmtpTranspo private function setHandlerParams() { foreach ($this->handlers as $keyword => $handler) { - if (array_key_exists($keyword, $this->capabilities)) { + if (\array_key_exists($keyword, $this->capabilities)) { $handler->setKeywordParams($this->capabilities[$keyword]); } } @@ -436,7 +436,7 @@ class Swift_Transport_EsmtpTransport extends Swift_Transport_AbstractSmtpTranspo { $handlers = []; foreach ($this->handlers as $keyword => $handler) { - if (array_key_exists($keyword, $this->capabilities)) { + if (\array_key_exists($keyword, $this->capabilities)) { $handlers[] = $handler; } } diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php index 21bce4b60..1a4b4754f 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php @@ -33,7 +33,7 @@ class Swift_Transport_FailoverTransport extends Swift_Transport_LoadBalancedTran */ public function ping() { - $maxTransports = count($this->transports); + $maxTransports = \count($this->transports); for ($i = 0; $i < $maxTransports && $transport = $this->getNextTransport(); ++$i) { if ($transport->ping()) { @@ -43,7 +43,7 @@ class Swift_Transport_FailoverTransport extends Swift_Transport_LoadBalancedTran } } - return count($this->transports) > 0; + return \count($this->transports) > 0; } /** @@ -58,7 +58,7 @@ class Swift_Transport_FailoverTransport extends Swift_Transport_LoadBalancedTran */ public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null) { - $maxTransports = count($this->transports); + $maxTransports = \count($this->transports); $sent = 0; $this->lastUsedTransport = null; @@ -79,10 +79,8 @@ class Swift_Transport_FailoverTransport extends Swift_Transport_LoadBalancedTran } } - if (0 == count($this->transports)) { - throw new Swift_TransportException( - 'All Transports in FailoverTransport failed, or no Transports available' - ); + if (0 == \count($this->transports)) { + throw new Swift_TransportException('All Transports in FailoverTransport failed, or no Transports available'); } return $sent; diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php index af97adf1f..50f1e5e40 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php @@ -25,8 +25,6 @@ interface Swift_Transport_IoBuffer extends Swift_InputByteStream, Swift_OutputBy * Perform any initialization needed, using the given $params. * * Parameters will vary depending upon the type of IoBuffer used. - * - * @param array $params */ public function initialize(array $params); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php index a12ce8d2d..0b5ba9d30 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/LoadBalancedTransport.php @@ -79,7 +79,7 @@ class Swift_Transport_LoadBalancedTransport implements Swift_Transport */ public function isStarted() { - return count($this->transports) > 0; + return \count($this->transports) > 0; } /** @@ -111,7 +111,7 @@ class Swift_Transport_LoadBalancedTransport implements Swift_Transport } } - return count($this->transports) > 0; + return \count($this->transports) > 0; } /** @@ -126,7 +126,7 @@ class Swift_Transport_LoadBalancedTransport implements Swift_Transport */ public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null) { - $maxTransports = count($this->transports); + $maxTransports = \count($this->transports); $sent = 0; $this->lastUsedTransport = null; @@ -145,10 +145,8 @@ class Swift_Transport_LoadBalancedTransport implements Swift_Transport } } - if (0 == count($this->transports)) { - throw new Swift_TransportException( - 'All Transports in LoadBalancedTransport failed, or no Transports available' - ); + if (0 == \count($this->transports)) { + throw new Swift_TransportException('All Transports in LoadBalancedTransport failed, or no Transports available'); } return $sent; diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/NullTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/NullTransport.php index 5934ca93b..7d910db5a 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/NullTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/NullTransport.php @@ -80,9 +80,9 @@ class Swift_Transport_NullTransport implements Swift_Transport } $count = ( - count((array) $message->getTo()) - + count((array) $message->getCc()) - + count((array) $message->getBcc()) + \count((array) $message->getTo()) + + \count((array) $message->getCc()) + + \count((array) $message->getBcc()) ); return $count; diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php index 7f0476ada..72ddae845 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php @@ -122,9 +122,9 @@ class Swift_Transport_SendmailTransport extends Swift_Transport_AbstractSmtpTran $buffer->setWriteTranslations(["\r\n" => "\n"]); } - $count = count((array) $message->getTo()) - + count((array) $message->getCc()) - + count((array) $message->getBcc()) + $count = \count((array) $message->getTo()) + + \count((array) $message->getCc()) + + \count((array) $message->getBcc()) ; $message->toByteStream($buffer); $buffer->flushBuffers(); diff --git a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php index 5f7b8ac9e..70782ada0 100644 --- a/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php +++ b/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php @@ -160,14 +160,10 @@ class Swift_Transport_StreamBuffer extends Swift_ByteStream_AbstractFilterableIn { if (isset($this->out) && !feof($this->out)) { $line = fgets($this->out); - if (0 == strlen($line)) { + if (0 == \strlen($line)) { $metas = stream_get_meta_data($this->out); if ($metas['timed_out']) { - throw new Swift_IoException( - 'Connection to '. - $this->getReadConnectionDescription(). - ' Timed Out' - ); + throw new Swift_IoException('Connection to '.$this->getReadConnectionDescription().' Timed Out'); } } @@ -192,14 +188,10 @@ class Swift_Transport_StreamBuffer extends Swift_ByteStream_AbstractFilterableIn { if (isset($this->out) && !feof($this->out)) { $ret = fread($this->out, $length); - if (0 == strlen($ret)) { + if (0 == \strlen($ret)) { $metas = stream_get_meta_data($this->out); if ($metas['timed_out']) { - throw new Swift_IoException( - 'Connection to '. - $this->getReadConnectionDescription(). - ' Timed Out' - ); + throw new Swift_IoException('Connection to '.$this->getReadConnectionDescription().' Timed Out'); } } @@ -224,7 +216,7 @@ class Swift_Transport_StreamBuffer extends Swift_ByteStream_AbstractFilterableIn protected function doCommit($bytes) { if (isset($this->in)) { - $bytesToWrite = strlen($bytes); + $bytesToWrite = \strlen($bytes); $totalBytesWritten = 0; while ($totalBytesWritten < $bytesToWrite) { @@ -299,9 +291,7 @@ class Swift_Transport_StreamBuffer extends Swift_ByteStream_AbstractFilterableIn $this->stream = proc_open($command, $descriptorSpec, $pipes); stream_set_blocking($pipes[2], 0); if ($err = stream_get_contents($pipes[2])) { - throw new Swift_TransportException( - 'Process could not be started ['.$err.']' - ); + throw new Swift_TransportException('Process could not be started ['.$err.']'); } $this->in = &$pipes[0]; $this->out = &$pipes[1]; diff --git a/vendor/swiftmailer/swiftmailer/lib/swiftmailer_generate_mimes_config.php b/vendor/swiftmailer/swiftmailer/lib/swiftmailer_generate_mimes_config.php index 3b940b7f1..c9e19d320 100644 --- a/vendor/swiftmailer/swiftmailer/lib/swiftmailer_generate_mimes_config.php +++ b/vendor/swiftmailer/swiftmailer/lib/swiftmailer_generate_mimes_config.php @@ -1,8 +1,8 @@ #!/usr/bin/php '{$mime_type}'"; @@ -156,7 +156,7 @@ function generateUpToDateMimeArray() $extension = strtolower(trim($node->glob['ddpattern'][0], '*.')); // skip none glob extensions and check if string length between 1 and 10 - if (false !== strpos($extension, '.') || strlen($extension) < 1 || strlen($extension) > 9) { + if (false !== strpos($extension, '.') || \strlen($extension) < 1 || \strlen($extension) > 9) { continue; } diff --git a/vendor/symfony/css-selector/CHANGELOG.md b/vendor/symfony/css-selector/CHANGELOG.md index 4061ff20c..de81fa2e7 100644 --- a/vendor/symfony/css-selector/CHANGELOG.md +++ b/vendor/symfony/css-selector/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +4.4.0 +----- + + * Added support for `*:only-of-type` + 2.8.0 ----- diff --git a/vendor/symfony/css-selector/CssSelectorConverter.php b/vendor/symfony/css-selector/CssSelectorConverter.php index 8d66dbd0e..bbb6afe21 100644 --- a/vendor/symfony/css-selector/CssSelectorConverter.php +++ b/vendor/symfony/css-selector/CssSelectorConverter.php @@ -27,16 +27,23 @@ use Symfony\Component\CssSelector\XPath\Translator; class CssSelectorConverter { private $translator; + private $cache; + + private static $xmlCache = []; + private static $htmlCache = []; /** * @param bool $html Whether HTML support should be enabled. Disable it for XML documents */ - public function __construct($html = true) + public function __construct(bool $html = true) { $this->translator = new Translator(); if ($html) { $this->translator->registerExtension(new HtmlExtension($this->translator)); + $this->cache = &self::$htmlCache; + } else { + $this->cache = &self::$xmlCache; } $this->translator @@ -53,13 +60,10 @@ class CssSelectorConverter * Optionally, a prefix can be added to the resulting XPath * expression with the $prefix parameter. * - * @param string $cssExpr The CSS expression - * @param string $prefix An optional prefix for the XPath expression - * * @return string */ - public function toXPath($cssExpr, $prefix = 'descendant-or-self::') + public function toXPath(string $cssExpr, string $prefix = 'descendant-or-self::') { - return $this->translator->cssToXPath($cssExpr, $prefix); + return $this->cache[$prefix][$cssExpr] ?? $this->cache[$prefix][$cssExpr] = $this->translator->cssToXPath($cssExpr, $prefix); } } diff --git a/vendor/symfony/css-selector/Exception/ExceptionInterface.php b/vendor/symfony/css-selector/Exception/ExceptionInterface.php index e4c5ae1b6..9e259006b 100644 --- a/vendor/symfony/css-selector/Exception/ExceptionInterface.php +++ b/vendor/symfony/css-selector/Exception/ExceptionInterface.php @@ -19,6 +19,6 @@ namespace Symfony\Component\CssSelector\Exception; * * @author Jean-François Simon */ -interface ExceptionInterface +interface ExceptionInterface extends \Throwable { } diff --git a/vendor/symfony/css-selector/Exception/SyntaxErrorException.php b/vendor/symfony/css-selector/Exception/SyntaxErrorException.php index 1200c979e..7deacf9c5 100644 --- a/vendor/symfony/css-selector/Exception/SyntaxErrorException.php +++ b/vendor/symfony/css-selector/Exception/SyntaxErrorException.php @@ -24,32 +24,25 @@ use Symfony\Component\CssSelector\Parser\Token; class SyntaxErrorException extends ParseException { /** - * @param string $expectedValue - * * @return self */ - public static function unexpectedToken($expectedValue, Token $foundToken) + public static function unexpectedToken(string $expectedValue, Token $foundToken) { return new self(sprintf('Expected %s, but %s found.', $expectedValue, $foundToken)); } /** - * @param string $pseudoElement - * @param string $unexpectedLocation - * * @return self */ - public static function pseudoElementFound($pseudoElement, $unexpectedLocation) + public static function pseudoElementFound(string $pseudoElement, string $unexpectedLocation) { return new self(sprintf('Unexpected pseudo-element "::%s" found %s.', $pseudoElement, $unexpectedLocation)); } /** - * @param int $position - * * @return self */ - public static function unclosedString($position) + public static function unclosedString(int $position) { return new self(sprintf('Unclosed/invalid string at %s.', $position)); } diff --git a/vendor/symfony/css-selector/LICENSE b/vendor/symfony/css-selector/LICENSE index 9e936ec04..9ff2d0d63 100644 --- a/vendor/symfony/css-selector/LICENSE +++ b/vendor/symfony/css-selector/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2020 Fabien Potencier +Copyright (c) 2004-2021 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 diff --git a/vendor/symfony/css-selector/Node/AbstractNode.php b/vendor/symfony/css-selector/Node/AbstractNode.php index de2e74aa8..1306aeacb 100644 --- a/vendor/symfony/css-selector/Node/AbstractNode.php +++ b/vendor/symfony/css-selector/Node/AbstractNode.php @@ -28,10 +28,7 @@ abstract class AbstractNode implements NodeInterface */ private $nodeName; - /** - * @return string - */ - public function getNodeName() + public function getNodeName(): string { if (null === $this->nodeName) { $this->nodeName = preg_replace('~.*\\\\([^\\\\]+)Node$~', '$1', static::class); diff --git a/vendor/symfony/css-selector/Node/AttributeNode.php b/vendor/symfony/css-selector/Node/AttributeNode.php index c09d92477..bf702d9ce 100644 --- a/vendor/symfony/css-selector/Node/AttributeNode.php +++ b/vendor/symfony/css-selector/Node/AttributeNode.php @@ -29,13 +29,7 @@ class AttributeNode extends AbstractNode private $operator; private $value; - /** - * @param string $namespace - * @param string $attribute - * @param string $operator - * @param string $value - */ - public function __construct(NodeInterface $selector, $namespace, $attribute, $operator, $value) + public function __construct(NodeInterface $selector, ?string $namespace, string $attribute, string $operator, ?string $value) { $this->selector = $selector; $this->namespace = $namespace; @@ -44,42 +38,27 @@ class AttributeNode extends AbstractNode $this->value = $value; } - /** - * @return NodeInterface - */ - public function getSelector() + public function getSelector(): NodeInterface { return $this->selector; } - /** - * @return string - */ - public function getNamespace() + public function getNamespace(): ?string { return $this->namespace; } - /** - * @return string - */ - public function getAttribute() + public function getAttribute(): string { return $this->attribute; } - /** - * @return string - */ - public function getOperator() + public function getOperator(): string { return $this->operator; } - /** - * @return string - */ - public function getValue() + public function getValue(): ?string { return $this->value; } @@ -87,7 +66,7 @@ class AttributeNode extends AbstractNode /** * {@inheritdoc} */ - public function getSpecificity() + public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0)); } @@ -95,7 +74,7 @@ class AttributeNode extends AbstractNode /** * {@inheritdoc} */ - public function __toString() + public function __toString(): string { $attribute = $this->namespace ? $this->namespace.'|'.$this->attribute : $this->attribute; diff --git a/vendor/symfony/css-selector/Node/ClassNode.php b/vendor/symfony/css-selector/Node/ClassNode.php index 866607cba..1998b4bd5 100644 --- a/vendor/symfony/css-selector/Node/ClassNode.php +++ b/vendor/symfony/css-selector/Node/ClassNode.php @@ -26,27 +26,18 @@ class ClassNode extends AbstractNode private $selector; private $name; - /** - * @param string $name - */ - public function __construct(NodeInterface $selector, $name) + public function __construct(NodeInterface $selector, string $name) { $this->selector = $selector; $this->name = $name; } - /** - * @return NodeInterface - */ - public function getSelector() + public function getSelector(): NodeInterface { return $this->selector; } - /** - * @return string - */ - public function getName() + public function getName(): string { return $this->name; } @@ -54,7 +45,7 @@ class ClassNode extends AbstractNode /** * {@inheritdoc} */ - public function getSpecificity() + public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0)); } @@ -62,7 +53,7 @@ class ClassNode extends AbstractNode /** * {@inheritdoc} */ - public function __toString() + public function __toString(): string { return sprintf('%s[%s.%s]', $this->getNodeName(), $this->selector, $this->name); } diff --git a/vendor/symfony/css-selector/Node/CombinedSelectorNode.php b/vendor/symfony/css-selector/Node/CombinedSelectorNode.php index 27b022485..f97fd21ae 100644 --- a/vendor/symfony/css-selector/Node/CombinedSelectorNode.php +++ b/vendor/symfony/css-selector/Node/CombinedSelectorNode.php @@ -27,36 +27,24 @@ class CombinedSelectorNode extends AbstractNode private $combinator; private $subSelector; - /** - * @param string $combinator - */ - public function __construct(NodeInterface $selector, $combinator, NodeInterface $subSelector) + public function __construct(NodeInterface $selector, string $combinator, NodeInterface $subSelector) { $this->selector = $selector; $this->combinator = $combinator; $this->subSelector = $subSelector; } - /** - * @return NodeInterface - */ - public function getSelector() + public function getSelector(): NodeInterface { return $this->selector; } - /** - * @return string - */ - public function getCombinator() + public function getCombinator(): string { return $this->combinator; } - /** - * @return NodeInterface - */ - public function getSubSelector() + public function getSubSelector(): NodeInterface { return $this->subSelector; } @@ -64,7 +52,7 @@ class CombinedSelectorNode extends AbstractNode /** * {@inheritdoc} */ - public function getSpecificity() + public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity()); } @@ -72,7 +60,7 @@ class CombinedSelectorNode extends AbstractNode /** * {@inheritdoc} */ - public function __toString() + public function __toString(): string { $combinator = ' ' === $this->combinator ? '' : $this->combinator; diff --git a/vendor/symfony/css-selector/Node/ElementNode.php b/vendor/symfony/css-selector/Node/ElementNode.php index 54869af6c..7949ed919 100644 --- a/vendor/symfony/css-selector/Node/ElementNode.php +++ b/vendor/symfony/css-selector/Node/ElementNode.php @@ -26,28 +26,18 @@ class ElementNode extends AbstractNode private $namespace; private $element; - /** - * @param string|null $namespace - * @param string|null $element - */ - public function __construct($namespace = null, $element = null) + public function __construct(string $namespace = null, string $element = null) { $this->namespace = $namespace; $this->element = $element; } - /** - * @return string|null - */ - public function getNamespace() + public function getNamespace(): ?string { return $this->namespace; } - /** - * @return string|null - */ - public function getElement() + public function getElement(): ?string { return $this->element; } @@ -55,7 +45,7 @@ class ElementNode extends AbstractNode /** * {@inheritdoc} */ - public function getSpecificity() + public function getSpecificity(): Specificity { return new Specificity(0, 0, $this->element ? 1 : 0); } @@ -63,7 +53,7 @@ class ElementNode extends AbstractNode /** * {@inheritdoc} */ - public function __toString() + public function __toString(): string { $element = $this->element ?: '*'; diff --git a/vendor/symfony/css-selector/Node/FunctionNode.php b/vendor/symfony/css-selector/Node/FunctionNode.php index b6f95e975..d3e9b4fc7 100644 --- a/vendor/symfony/css-selector/Node/FunctionNode.php +++ b/vendor/symfony/css-selector/Node/FunctionNode.php @@ -30,28 +30,21 @@ class FunctionNode extends AbstractNode private $arguments; /** - * @param string $name * @param Token[] $arguments */ - public function __construct(NodeInterface $selector, $name, array $arguments = []) + public function __construct(NodeInterface $selector, string $name, array $arguments = []) { $this->selector = $selector; $this->name = strtolower($name); $this->arguments = $arguments; } - /** - * @return NodeInterface - */ - public function getSelector() + public function getSelector(): NodeInterface { return $this->selector; } - /** - * @return string - */ - public function getName() + public function getName(): string { return $this->name; } @@ -59,7 +52,7 @@ class FunctionNode extends AbstractNode /** * @return Token[] */ - public function getArguments() + public function getArguments(): array { return $this->arguments; } @@ -67,7 +60,7 @@ class FunctionNode extends AbstractNode /** * {@inheritdoc} */ - public function getSpecificity() + public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0)); } @@ -75,7 +68,7 @@ class FunctionNode extends AbstractNode /** * {@inheritdoc} */ - public function __toString() + public function __toString(): string { $arguments = implode(', ', array_map(function (Token $token) { return "'".$token->getValue()."'"; diff --git a/vendor/symfony/css-selector/Node/HashNode.php b/vendor/symfony/css-selector/Node/HashNode.php index 3ea89dc18..f73fa2e74 100644 --- a/vendor/symfony/css-selector/Node/HashNode.php +++ b/vendor/symfony/css-selector/Node/HashNode.php @@ -26,27 +26,18 @@ class HashNode extends AbstractNode private $selector; private $id; - /** - * @param string $id - */ - public function __construct(NodeInterface $selector, $id) + public function __construct(NodeInterface $selector, string $id) { $this->selector = $selector; $this->id = $id; } - /** - * @return NodeInterface - */ - public function getSelector() + public function getSelector(): NodeInterface { return $this->selector; } - /** - * @return string - */ - public function getId() + public function getId(): string { return $this->id; } @@ -54,7 +45,7 @@ class HashNode extends AbstractNode /** * {@inheritdoc} */ - public function getSpecificity() + public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus(new Specificity(1, 0, 0)); } @@ -62,7 +53,7 @@ class HashNode extends AbstractNode /** * {@inheritdoc} */ - public function __toString() + public function __toString(): string { return sprintf('%s[%s#%s]', $this->getNodeName(), $this->selector, $this->id); } diff --git a/vendor/symfony/css-selector/Node/NegationNode.php b/vendor/symfony/css-selector/Node/NegationNode.php index bf97caeb5..afa47cf87 100644 --- a/vendor/symfony/css-selector/Node/NegationNode.php +++ b/vendor/symfony/css-selector/Node/NegationNode.php @@ -32,18 +32,12 @@ class NegationNode extends AbstractNode $this->subSelector = $subSelector; } - /** - * @return NodeInterface - */ - public function getSelector() + public function getSelector(): NodeInterface { return $this->selector; } - /** - * @return NodeInterface - */ - public function getSubSelector() + public function getSubSelector(): NodeInterface { return $this->subSelector; } @@ -51,7 +45,7 @@ class NegationNode extends AbstractNode /** * {@inheritdoc} */ - public function getSpecificity() + public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity()); } @@ -59,7 +53,7 @@ class NegationNode extends AbstractNode /** * {@inheritdoc} */ - public function __toString() + public function __toString(): string { return sprintf('%s[%s:not(%s)]', $this->getNodeName(), $this->selector, $this->subSelector); } diff --git a/vendor/symfony/css-selector/Node/NodeInterface.php b/vendor/symfony/css-selector/Node/NodeInterface.php index d919e20c7..b078d26d4 100644 --- a/vendor/symfony/css-selector/Node/NodeInterface.php +++ b/vendor/symfony/css-selector/Node/NodeInterface.php @@ -23,24 +23,9 @@ namespace Symfony\Component\CssSelector\Node; */ interface NodeInterface { - /** - * Returns node's name. - * - * @return string - */ - public function getNodeName(); + public function getNodeName(): string; - /** - * Returns node's specificity. - * - * @return Specificity - */ - public function getSpecificity(); + public function getSpecificity(): Specificity; - /** - * Returns node's string representation. - * - * @return string - */ - public function __toString(); + public function __toString(): string; } diff --git a/vendor/symfony/css-selector/Node/PseudoNode.php b/vendor/symfony/css-selector/Node/PseudoNode.php index c7d0b9fb3..7d4a011e1 100644 --- a/vendor/symfony/css-selector/Node/PseudoNode.php +++ b/vendor/symfony/css-selector/Node/PseudoNode.php @@ -26,27 +26,18 @@ class PseudoNode extends AbstractNode private $selector; private $identifier; - /** - * @param string $identifier - */ - public function __construct(NodeInterface $selector, $identifier) + public function __construct(NodeInterface $selector, string $identifier) { $this->selector = $selector; $this->identifier = strtolower($identifier); } - /** - * @return NodeInterface - */ - public function getSelector() + public function getSelector(): NodeInterface { return $this->selector; } - /** - * @return string - */ - public function getIdentifier() + public function getIdentifier(): string { return $this->identifier; } @@ -54,7 +45,7 @@ class PseudoNode extends AbstractNode /** * {@inheritdoc} */ - public function getSpecificity() + public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0)); } @@ -62,7 +53,7 @@ class PseudoNode extends AbstractNode /** * {@inheritdoc} */ - public function __toString() + public function __toString(): string { return sprintf('%s[%s:%s]', $this->getNodeName(), $this->selector, $this->identifier); } diff --git a/vendor/symfony/css-selector/Node/SelectorNode.php b/vendor/symfony/css-selector/Node/SelectorNode.php index 2379babff..a76aa5bb5 100644 --- a/vendor/symfony/css-selector/Node/SelectorNode.php +++ b/vendor/symfony/css-selector/Node/SelectorNode.php @@ -26,27 +26,18 @@ class SelectorNode extends AbstractNode private $tree; private $pseudoElement; - /** - * @param string|null $pseudoElement - */ - public function __construct(NodeInterface $tree, $pseudoElement = null) + public function __construct(NodeInterface $tree, string $pseudoElement = null) { $this->tree = $tree; $this->pseudoElement = $pseudoElement ? strtolower($pseudoElement) : null; } - /** - * @return NodeInterface - */ - public function getTree() + public function getTree(): NodeInterface { return $this->tree; } - /** - * @return string|null - */ - public function getPseudoElement() + public function getPseudoElement(): ?string { return $this->pseudoElement; } @@ -54,7 +45,7 @@ class SelectorNode extends AbstractNode /** * {@inheritdoc} */ - public function getSpecificity() + public function getSpecificity(): Specificity { return $this->tree->getSpecificity()->plus(new Specificity(0, 0, $this->pseudoElement ? 1 : 0)); } @@ -62,7 +53,7 @@ class SelectorNode extends AbstractNode /** * {@inheritdoc} */ - public function __toString() + public function __toString(): string { return sprintf('%s[%s%s]', $this->getNodeName(), $this->tree, $this->pseudoElement ? '::'.$this->pseudoElement : ''); } diff --git a/vendor/symfony/css-selector/Node/Specificity.php b/vendor/symfony/css-selector/Node/Specificity.php index a11b7f73d..b00f6d281 100644 --- a/vendor/symfony/css-selector/Node/Specificity.php +++ b/vendor/symfony/css-selector/Node/Specificity.php @@ -25,40 +25,27 @@ namespace Symfony\Component\CssSelector\Node; */ class Specificity { - const A_FACTOR = 100; - const B_FACTOR = 10; - const C_FACTOR = 1; + public const A_FACTOR = 100; + public const B_FACTOR = 10; + public const C_FACTOR = 1; private $a; private $b; private $c; - /** - * @param int $a - * @param int $b - * @param int $c - */ - public function __construct($a, $b, $c) + public function __construct(int $a, int $b, int $c) { $this->a = $a; $this->b = $b; $this->c = $c; } - /** - * @return self - */ - public function plus(self $specificity) + public function plus(self $specificity): self { return new self($this->a + $specificity->a, $this->b + $specificity->b, $this->c + $specificity->c); } - /** - * Returns global specificity value. - * - * @return int - */ - public function getValue() + public function getValue(): int { return $this->a * self::A_FACTOR + $this->b * self::B_FACTOR + $this->c * self::C_FACTOR; } @@ -66,10 +53,8 @@ class Specificity /** * Returns -1 if the object specificity is lower than the argument, * 0 if they are equal, and 1 if the argument is lower. - * - * @return int */ - public function compareTo(self $specificity) + public function compareTo(self $specificity): int { if ($this->a !== $specificity->a) { return $this->a > $specificity->a ? 1 : -1; diff --git a/vendor/symfony/css-selector/Parser/Handler/CommentHandler.php b/vendor/symfony/css-selector/Parser/Handler/CommentHandler.php index a29775cab..93f318844 100644 --- a/vendor/symfony/css-selector/Parser/Handler/CommentHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/CommentHandler.php @@ -29,7 +29,7 @@ class CommentHandler implements HandlerInterface /** * {@inheritdoc} */ - public function handle(Reader $reader, TokenStream $stream) + public function handle(Reader $reader, TokenStream $stream): bool { if ('/*' !== $reader->getSubstring(2)) { return false; diff --git a/vendor/symfony/css-selector/Parser/Handler/HandlerInterface.php b/vendor/symfony/css-selector/Parser/Handler/HandlerInterface.php index de931f679..9ec714d54 100644 --- a/vendor/symfony/css-selector/Parser/Handler/HandlerInterface.php +++ b/vendor/symfony/css-selector/Parser/Handler/HandlerInterface.php @@ -26,8 +26,5 @@ use Symfony\Component\CssSelector\Parser\TokenStream; */ interface HandlerInterface { - /** - * @return bool - */ - public function handle(Reader $reader, TokenStream $stream); + public function handle(Reader $reader, TokenStream $stream): bool; } diff --git a/vendor/symfony/css-selector/Parser/Handler/HashHandler.php b/vendor/symfony/css-selector/Parser/Handler/HashHandler.php index e451328f1..7ae9b438c 100644 --- a/vendor/symfony/css-selector/Parser/Handler/HashHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/HashHandler.php @@ -41,7 +41,7 @@ class HashHandler implements HandlerInterface /** * {@inheritdoc} */ - public function handle(Reader $reader, TokenStream $stream) + public function handle(Reader $reader, TokenStream $stream): bool { $match = $reader->findPattern($this->patterns->getHashPattern()); diff --git a/vendor/symfony/css-selector/Parser/Handler/IdentifierHandler.php b/vendor/symfony/css-selector/Parser/Handler/IdentifierHandler.php index 1591fcb54..7b2a14e2c 100644 --- a/vendor/symfony/css-selector/Parser/Handler/IdentifierHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/IdentifierHandler.php @@ -41,7 +41,7 @@ class IdentifierHandler implements HandlerInterface /** * {@inheritdoc} */ - public function handle(Reader $reader, TokenStream $stream) + public function handle(Reader $reader, TokenStream $stream): bool { $match = $reader->findPattern($this->patterns->getIdentifierPattern()); diff --git a/vendor/symfony/css-selector/Parser/Handler/NumberHandler.php b/vendor/symfony/css-selector/Parser/Handler/NumberHandler.php index 5955903cd..8291a68d1 100644 --- a/vendor/symfony/css-selector/Parser/Handler/NumberHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/NumberHandler.php @@ -38,7 +38,7 @@ class NumberHandler implements HandlerInterface /** * {@inheritdoc} */ - public function handle(Reader $reader, TokenStream $stream) + public function handle(Reader $reader, TokenStream $stream): bool { $match = $reader->findPattern($this->patterns->getNumberPattern()); diff --git a/vendor/symfony/css-selector/Parser/Handler/StringHandler.php b/vendor/symfony/css-selector/Parser/Handler/StringHandler.php index 72e94c3d5..6ce83cdc9 100644 --- a/vendor/symfony/css-selector/Parser/Handler/StringHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/StringHandler.php @@ -43,7 +43,7 @@ class StringHandler implements HandlerInterface /** * {@inheritdoc} */ - public function handle(Reader $reader, TokenStream $stream) + public function handle(Reader $reader, TokenStream $stream): bool { $quote = $reader->getSubstring(1); diff --git a/vendor/symfony/css-selector/Parser/Handler/WhitespaceHandler.php b/vendor/symfony/css-selector/Parser/Handler/WhitespaceHandler.php index 396467af0..21345e32c 100644 --- a/vendor/symfony/css-selector/Parser/Handler/WhitespaceHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/WhitespaceHandler.php @@ -30,7 +30,7 @@ class WhitespaceHandler implements HandlerInterface /** * {@inheritdoc} */ - public function handle(Reader $reader, TokenStream $stream) + public function handle(Reader $reader, TokenStream $stream): bool { $match = $reader->findPattern('~^[ \t\r\n\f]+~'); diff --git a/vendor/symfony/css-selector/Parser/Parser.php b/vendor/symfony/css-selector/Parser/Parser.php index 7b131efdb..63e883dcf 100644 --- a/vendor/symfony/css-selector/Parser/Parser.php +++ b/vendor/symfony/css-selector/Parser/Parser.php @@ -37,7 +37,7 @@ class Parser implements ParserInterface /** * {@inheritdoc} */ - public function parse($source) + public function parse(string $source): array { $reader = new Reader($source); $stream = $this->tokenizer->tokenize($reader); @@ -50,11 +50,9 @@ class Parser implements ParserInterface * * @param Token[] $tokens * - * @return array - * * @throws SyntaxErrorException */ - public static function parseSeries(array $tokens) + public static function parseSeries(array $tokens): array { foreach ($tokens as $token) { if ($token->isString()) { @@ -86,7 +84,7 @@ class Parser implements ParserInterface } $split = explode('n', $joined); - $first = isset($split[0]) ? $split[0] : null; + $first = $split[0] ?? null; return [ $first ? ('-' === $first || '+' === $first ? $int($first.'1') : $int($first)) : 1, @@ -94,12 +92,7 @@ class Parser implements ParserInterface ]; } - /** - * Parses selector nodes. - * - * @return array - */ - private function parseSelectorList(TokenStream $stream) + private function parseSelectorList(TokenStream $stream): array { $stream->skipWhitespace(); $selectors = []; @@ -118,16 +111,9 @@ class Parser implements ParserInterface return $selectors; } - /** - * Parses next selector or combined node. - * - * @return Node\SelectorNode - * - * @throws SyntaxErrorException - */ - private function parserSelectorNode(TokenStream $stream) + private function parserSelectorNode(TokenStream $stream): Node\SelectorNode { - list($result, $pseudoElement) = $this->parseSimpleSelector($stream); + [$result, $pseudoElement] = $this->parseSimpleSelector($stream); while (true) { $stream->skipWhitespace(); @@ -148,7 +134,7 @@ class Parser implements ParserInterface $combinator = ' '; } - list($nextSelector, $pseudoElement) = $this->parseSimpleSelector($stream); + [$nextSelector, $pseudoElement] = $this->parseSimpleSelector($stream); $result = new Node\CombinedSelectorNode($result, $combinator, $nextSelector); } @@ -158,13 +144,9 @@ class Parser implements ParserInterface /** * Parses next simple node (hash, class, pseudo, negation). * - * @param bool $insideNegation - * - * @return array - * * @throws SyntaxErrorException */ - private function parseSimpleSelector(TokenStream $stream, $insideNegation = false) + private function parseSimpleSelector(TokenStream $stream, bool $insideNegation = false): array { $stream->skipWhitespace(); @@ -227,7 +209,7 @@ class Parser implements ParserInterface throw SyntaxErrorException::nestedNot(); } - list($argument, $argumentPseudoElement) = $this->parseSimpleSelector($stream, true); + [$argument, $argumentPseudoElement] = $this->parseSimpleSelector($stream, true); $next = $stream->getNext(); if (null !== $argumentPseudoElement) { @@ -278,12 +260,7 @@ class Parser implements ParserInterface return [$result, $pseudoElement]; } - /** - * Parses next element node. - * - * @return Node\ElementNode - */ - private function parseElementNode(TokenStream $stream) + private function parseElementNode(TokenStream $stream): Node\ElementNode { $peek = $stream->getPeek(); @@ -309,14 +286,7 @@ class Parser implements ParserInterface return new Node\ElementNode($namespace, $element); } - /** - * Parses next attribute node. - * - * @return Node\AttributeNode - * - * @throws SyntaxErrorException - */ - private function parseAttributeNode(Node\NodeInterface $selector, TokenStream $stream) + private function parseAttributeNode(Node\NodeInterface $selector, TokenStream $stream): Node\AttributeNode { $stream->skipWhitespace(); $attribute = $stream->getNextIdentifierOrStar(); diff --git a/vendor/symfony/css-selector/Parser/ParserInterface.php b/vendor/symfony/css-selector/Parser/ParserInterface.php index c5af20367..51c3d9350 100644 --- a/vendor/symfony/css-selector/Parser/ParserInterface.php +++ b/vendor/symfony/css-selector/Parser/ParserInterface.php @@ -28,9 +28,7 @@ interface ParserInterface /** * Parses given selector source into an array of tokens. * - * @param string $source - * * @return SelectorNode[] */ - public function parse($source); + public function parse(string $source): array; } diff --git a/vendor/symfony/css-selector/Parser/Reader.php b/vendor/symfony/css-selector/Parser/Reader.php index 076cb711c..4b43effed 100644 --- a/vendor/symfony/css-selector/Parser/Reader.php +++ b/vendor/symfony/css-selector/Parser/Reader.php @@ -27,56 +27,33 @@ class Reader private $length; private $position = 0; - /** - * @param string $source - */ - public function __construct($source) + public function __construct(string $source) { $this->source = $source; $this->length = \strlen($source); } - /** - * @return bool - */ - public function isEOF() + public function isEOF(): bool { return $this->position >= $this->length; } - /** - * @return int - */ - public function getPosition() + public function getPosition(): int { return $this->position; } - /** - * @return int - */ - public function getRemainingLength() + public function getRemainingLength(): int { return $this->length - $this->position; } - /** - * @param int $length - * @param int $offset - * - * @return string - */ - public function getSubstring($length, $offset = 0) + public function getSubstring(int $length, int $offset = 0): string { return substr($this->source, $this->position + $offset, $length); } - /** - * @param string $string - * - * @return int - */ - public function getOffset($string) + public function getOffset(string $string) { $position = strpos($this->source, $string, $this->position); @@ -84,11 +61,9 @@ class Reader } /** - * @param string $pattern - * * @return array|false */ - public function findPattern($pattern) + public function findPattern(string $pattern) { $source = substr($this->source, $this->position); @@ -99,10 +74,7 @@ class Reader return false; } - /** - * @param int $length - */ - public function moveForward($length) + public function moveForward(int $length) { $this->position += $length; } diff --git a/vendor/symfony/css-selector/Parser/Shortcut/ClassParser.php b/vendor/symfony/css-selector/Parser/Shortcut/ClassParser.php index 3b9200623..17fa8c27e 100644 --- a/vendor/symfony/css-selector/Parser/Shortcut/ClassParser.php +++ b/vendor/symfony/css-selector/Parser/Shortcut/ClassParser.php @@ -31,7 +31,7 @@ class ClassParser implements ParserInterface /** * {@inheritdoc} */ - public function parse($source) + public function parse(string $source): array { // Matches an optional namespace, optional element, and required class // $source = 'test|input.ab6bd_field'; diff --git a/vendor/symfony/css-selector/Parser/Shortcut/ElementParser.php b/vendor/symfony/css-selector/Parser/Shortcut/ElementParser.php index 392c6aabd..8b9a86386 100644 --- a/vendor/symfony/css-selector/Parser/Shortcut/ElementParser.php +++ b/vendor/symfony/css-selector/Parser/Shortcut/ElementParser.php @@ -30,7 +30,7 @@ class ElementParser implements ParserInterface /** * {@inheritdoc} */ - public function parse($source) + public function parse(string $source): array { // Matches an optional namespace, required element or `*` // $source = 'testns|testel'; diff --git a/vendor/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php b/vendor/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php index 276b57405..222df5cd2 100644 --- a/vendor/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php +++ b/vendor/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php @@ -34,7 +34,7 @@ class EmptyStringParser implements ParserInterface /** * {@inheritdoc} */ - public function parse($source) + public function parse(string $source): array { // Matches an empty string if ('' == $source) { diff --git a/vendor/symfony/css-selector/Parser/Shortcut/HashParser.php b/vendor/symfony/css-selector/Parser/Shortcut/HashParser.php index 0ffcb6dee..fb07ee6cf 100644 --- a/vendor/symfony/css-selector/Parser/Shortcut/HashParser.php +++ b/vendor/symfony/css-selector/Parser/Shortcut/HashParser.php @@ -31,7 +31,7 @@ class HashParser implements ParserInterface /** * {@inheritdoc} */ - public function parse($source) + public function parse(string $source): array { // Matches an optional namespace, optional element, and required id // $source = 'test|input#ab6bd_field'; diff --git a/vendor/symfony/css-selector/Parser/Token.php b/vendor/symfony/css-selector/Parser/Token.php index d641da865..a053203c0 100644 --- a/vendor/symfony/css-selector/Parser/Token.php +++ b/vendor/symfony/css-selector/Parser/Token.php @@ -23,66 +23,46 @@ namespace Symfony\Component\CssSelector\Parser; */ class Token { - const TYPE_FILE_END = 'eof'; - const TYPE_DELIMITER = 'delimiter'; - const TYPE_WHITESPACE = 'whitespace'; - const TYPE_IDENTIFIER = 'identifier'; - const TYPE_HASH = 'hash'; - const TYPE_NUMBER = 'number'; - const TYPE_STRING = 'string'; + public const TYPE_FILE_END = 'eof'; + public const TYPE_DELIMITER = 'delimiter'; + public const TYPE_WHITESPACE = 'whitespace'; + public const TYPE_IDENTIFIER = 'identifier'; + public const TYPE_HASH = 'hash'; + public const TYPE_NUMBER = 'number'; + public const TYPE_STRING = 'string'; private $type; private $value; private $position; - /** - * @param int $type - * @param string $value - * @param int $position - */ - public function __construct($type, $value, $position) + public function __construct(?string $type, ?string $value, ?int $position) { $this->type = $type; $this->value = $value; $this->position = $position; } - /** - * @return int - */ - public function getType() + public function getType(): ?int { return $this->type; } - /** - * @return string - */ - public function getValue() + public function getValue(): ?string { return $this->value; } - /** - * @return int - */ - public function getPosition() + public function getPosition(): ?int { return $this->position; } - /** - * @return bool - */ - public function isFileEnd() + public function isFileEnd(): bool { return self::TYPE_FILE_END === $this->type; } - /** - * @return bool - */ - public function isDelimiter(array $values = []) + public function isDelimiter(array $values = []): bool { if (self::TYPE_DELIMITER !== $this->type) { return false; @@ -95,50 +75,32 @@ class Token return \in_array($this->value, $values); } - /** - * @return bool - */ - public function isWhitespace() + public function isWhitespace(): bool { return self::TYPE_WHITESPACE === $this->type; } - /** - * @return bool - */ - public function isIdentifier() + public function isIdentifier(): bool { return self::TYPE_IDENTIFIER === $this->type; } - /** - * @return bool - */ - public function isHash() + public function isHash(): bool { return self::TYPE_HASH === $this->type; } - /** - * @return bool - */ - public function isNumber() + public function isNumber(): bool { return self::TYPE_NUMBER === $this->type; } - /** - * @return bool - */ - public function isString() + public function isString(): bool { return self::TYPE_STRING === $this->type; } - /** - * @return string - */ - public function __toString() + public function __toString(): string { if ($this->value) { return sprintf('<%s "%s" at %s>', $this->type, $this->value, $this->position); diff --git a/vendor/symfony/css-selector/Parser/TokenStream.php b/vendor/symfony/css-selector/Parser/TokenStream.php index 001bfe1a7..f4c2585aa 100644 --- a/vendor/symfony/css-selector/Parser/TokenStream.php +++ b/vendor/symfony/css-selector/Parser/TokenStream.php @@ -56,7 +56,7 @@ class TokenStream * * @return $this */ - public function push(Token $token) + public function push(Token $token): self { $this->tokens[] = $token; @@ -68,7 +68,7 @@ class TokenStream * * @return $this */ - public function freeze() + public function freeze(): self { return $this; } @@ -76,11 +76,9 @@ class TokenStream /** * Returns next token. * - * @return Token - * * @throws InternalErrorException If there is no more token */ - public function getNext() + public function getNext(): Token { if ($this->peeking) { $this->peeking = false; @@ -98,10 +96,8 @@ class TokenStream /** * Returns peeked token. - * - * @return Token */ - public function getPeek() + public function getPeek(): Token { if (!$this->peeking) { $this->peeked = $this->getNext(); @@ -116,7 +112,7 @@ class TokenStream * * @return Token[] */ - public function getUsed() + public function getUsed(): array { return $this->used; } @@ -128,7 +124,7 @@ class TokenStream * * @throws SyntaxErrorException If next token is not an identifier */ - public function getNextIdentifier() + public function getNextIdentifier(): string { $next = $this->getNext(); @@ -146,7 +142,7 @@ class TokenStream * * @throws SyntaxErrorException If next token is not an identifier or a star delimiter */ - public function getNextIdentifierOrStar() + public function getNextIdentifierOrStar(): ?string { $next = $this->getNext(); diff --git a/vendor/symfony/css-selector/Parser/Tokenizer/Tokenizer.php b/vendor/symfony/css-selector/Parser/Tokenizer/Tokenizer.php index fc65bc684..e0dcc5bf1 100644 --- a/vendor/symfony/css-selector/Parser/Tokenizer/Tokenizer.php +++ b/vendor/symfony/css-selector/Parser/Tokenizer/Tokenizer.php @@ -50,10 +50,8 @@ class Tokenizer /** * Tokenize selector source code. - * - * @return TokenStream */ - public function tokenize(Reader $reader) + public function tokenize(Reader $reader): TokenStream { $stream = new TokenStream(); diff --git a/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php b/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php index ce322e96f..013e827d2 100644 --- a/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php +++ b/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php @@ -30,36 +30,21 @@ class TokenizerEscaping $this->patterns = $patterns; } - /** - * @param string $value - * - * @return string - */ - public function escapeUnicode($value) + public function escapeUnicode(string $value): string { $value = $this->replaceUnicodeSequences($value); return preg_replace($this->patterns->getSimpleEscapePattern(), '$1', $value); } - /** - * @param string $value - * - * @return string - */ - public function escapeUnicodeAndNewLine($value) + public function escapeUnicodeAndNewLine(string $value): string { $value = preg_replace($this->patterns->getNewLineEscapePattern(), '', $value); return $this->escapeUnicode($value); } - /** - * @param string $value - * - * @return string - */ - private function replaceUnicodeSequences($value) + private function replaceUnicodeSequences(string $value): string { return preg_replace_callback($this->patterns->getUnicodeEscapePattern(), function ($match) { $c = hexdec($match[1]); diff --git a/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php b/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php index bc6130d7d..5f16ac48f 100644 --- a/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php +++ b/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php @@ -52,60 +52,37 @@ class TokenizerPatterns $this->quotedStringPattern = '([^\n\r\f%s]|'.$this->stringEscapePattern.')*'; } - /** - * @return string - */ - public function getNewLineEscapePattern() + public function getNewLineEscapePattern(): string { return '~^'.$this->newLineEscapePattern.'~'; } - /** - * @return string - */ - public function getSimpleEscapePattern() + public function getSimpleEscapePattern(): string { return '~^'.$this->simpleEscapePattern.'~'; } - /** - * @return string - */ - public function getUnicodeEscapePattern() + public function getUnicodeEscapePattern(): string { return '~^'.$this->unicodeEscapePattern.'~i'; } - /** - * @return string - */ - public function getIdentifierPattern() + public function getIdentifierPattern(): string { return '~^'.$this->identifierPattern.'~i'; } - /** - * @return string - */ - public function getHashPattern() + public function getHashPattern(): string { return '~^'.$this->hashPattern.'~i'; } - /** - * @return string - */ - public function getNumberPattern() + public function getNumberPattern(): string { return '~^'.$this->numberPattern.'~'; } - /** - * @param string $quote - * - * @return string - */ - public function getQuotedStringPattern($quote) + public function getQuotedStringPattern(string $quote): string { return '~^'.sprintf($this->quotedStringPattern, $quote).'~i'; } diff --git a/vendor/symfony/css-selector/XPath/Extension/AbstractExtension.php b/vendor/symfony/css-selector/XPath/Extension/AbstractExtension.php index 1dce1eddf..44e0035a7 100644 --- a/vendor/symfony/css-selector/XPath/Extension/AbstractExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/AbstractExtension.php @@ -26,7 +26,7 @@ abstract class AbstractExtension implements ExtensionInterface /** * {@inheritdoc} */ - public function getNodeTranslators() + public function getNodeTranslators(): array { return []; } @@ -34,7 +34,7 @@ abstract class AbstractExtension implements ExtensionInterface /** * {@inheritdoc} */ - public function getCombinationTranslators() + public function getCombinationTranslators(): array { return []; } @@ -42,7 +42,7 @@ abstract class AbstractExtension implements ExtensionInterface /** * {@inheritdoc} */ - public function getFunctionTranslators() + public function getFunctionTranslators(): array { return []; } @@ -50,7 +50,7 @@ abstract class AbstractExtension implements ExtensionInterface /** * {@inheritdoc} */ - public function getPseudoClassTranslators() + public function getPseudoClassTranslators(): array { return []; } @@ -58,7 +58,7 @@ abstract class AbstractExtension implements ExtensionInterface /** * {@inheritdoc} */ - public function getAttributeMatchingTranslators() + public function getAttributeMatchingTranslators(): array { return []; } diff --git a/vendor/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php b/vendor/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php index f27878b14..a9879f1be 100644 --- a/vendor/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php @@ -29,7 +29,7 @@ class AttributeMatchingExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getAttributeMatchingTranslators() + public function getAttributeMatchingTranslators(): array { return [ 'exists' => [$this, 'translateExists'], @@ -43,35 +43,17 @@ class AttributeMatchingExtension extends AbstractExtension ]; } - /** - * @param string $attribute - * @param string $value - * - * @return XPathExpr - */ - public function translateExists(XPathExpr $xpath, $attribute, $value) + public function translateExists(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { return $xpath->addCondition($attribute); } - /** - * @param string $attribute - * @param string $value - * - * @return XPathExpr - */ - public function translateEquals(XPathExpr $xpath, $attribute, $value) + public function translateEquals(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { return $xpath->addCondition(sprintf('%s = %s', $attribute, Translator::getXpathLiteral($value))); } - /** - * @param string $attribute - * @param string $value - * - * @return XPathExpr - */ - public function translateIncludes(XPathExpr $xpath, $attribute, $value) + public function translateIncludes(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { return $xpath->addCondition($value ? sprintf( '%1$s and contains(concat(\' \', normalize-space(%1$s), \' \'), %2$s)', @@ -80,13 +62,7 @@ class AttributeMatchingExtension extends AbstractExtension ) : '0'); } - /** - * @param string $attribute - * @param string $value - * - * @return XPathExpr - */ - public function translateDashMatch(XPathExpr $xpath, $attribute, $value) + public function translateDashMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { return $xpath->addCondition(sprintf( '%1$s and (%1$s = %2$s or starts-with(%1$s, %3$s))', @@ -96,13 +72,7 @@ class AttributeMatchingExtension extends AbstractExtension )); } - /** - * @param string $attribute - * @param string $value - * - * @return XPathExpr - */ - public function translatePrefixMatch(XPathExpr $xpath, $attribute, $value) + public function translatePrefixMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { return $xpath->addCondition($value ? sprintf( '%1$s and starts-with(%1$s, %2$s)', @@ -111,13 +81,7 @@ class AttributeMatchingExtension extends AbstractExtension ) : '0'); } - /** - * @param string $attribute - * @param string $value - * - * @return XPathExpr - */ - public function translateSuffixMatch(XPathExpr $xpath, $attribute, $value) + public function translateSuffixMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { return $xpath->addCondition($value ? sprintf( '%1$s and substring(%1$s, string-length(%1$s)-%2$s) = %3$s', @@ -127,13 +91,7 @@ class AttributeMatchingExtension extends AbstractExtension ) : '0'); } - /** - * @param string $attribute - * @param string $value - * - * @return XPathExpr - */ - public function translateSubstringMatch(XPathExpr $xpath, $attribute, $value) + public function translateSubstringMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { return $xpath->addCondition($value ? sprintf( '%1$s and contains(%1$s, %2$s)', @@ -142,13 +100,7 @@ class AttributeMatchingExtension extends AbstractExtension ) : '0'); } - /** - * @param string $attribute - * @param string $value - * - * @return XPathExpr - */ - public function translateDifferent(XPathExpr $xpath, $attribute, $value) + public function translateDifferent(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { return $xpath->addCondition(sprintf( $value ? 'not(%1$s) or %1$s != %2$s' : '%s != %s', @@ -160,7 +112,7 @@ class AttributeMatchingExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return 'attribute-matching'; } diff --git a/vendor/symfony/css-selector/XPath/Extension/CombinationExtension.php b/vendor/symfony/css-selector/XPath/Extension/CombinationExtension.php index d962dc5ab..aee976e94 100644 --- a/vendor/symfony/css-selector/XPath/Extension/CombinationExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/CombinationExtension.php @@ -28,7 +28,7 @@ class CombinationExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getCombinationTranslators() + public function getCombinationTranslators(): array { return [ ' ' => [$this, 'translateDescendant'], @@ -38,26 +38,17 @@ class CombinationExtension extends AbstractExtension ]; } - /** - * @return XPathExpr - */ - public function translateDescendant(XPathExpr $xpath, XPathExpr $combinedXpath) + public function translateDescendant(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr { return $xpath->join('/descendant-or-self::*/', $combinedXpath); } - /** - * @return XPathExpr - */ - public function translateChild(XPathExpr $xpath, XPathExpr $combinedXpath) + public function translateChild(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr { return $xpath->join('/', $combinedXpath); } - /** - * @return XPathExpr - */ - public function translateDirectAdjacent(XPathExpr $xpath, XPathExpr $combinedXpath) + public function translateDirectAdjacent(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr { return $xpath ->join('/following-sibling::', $combinedXpath) @@ -65,10 +56,7 @@ class CombinationExtension extends AbstractExtension ->addCondition('position() = 1'); } - /** - * @return XPathExpr - */ - public function translateIndirectAdjacent(XPathExpr $xpath, XPathExpr $combinedXpath) + public function translateIndirectAdjacent(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr { return $xpath->join('/following-sibling::', $combinedXpath); } @@ -76,7 +64,7 @@ class CombinationExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return 'combination'; } diff --git a/vendor/symfony/css-selector/XPath/Extension/ExtensionInterface.php b/vendor/symfony/css-selector/XPath/Extension/ExtensionInterface.php index 360702289..1a74b90ac 100644 --- a/vendor/symfony/css-selector/XPath/Extension/ExtensionInterface.php +++ b/vendor/symfony/css-selector/XPath/Extension/ExtensionInterface.php @@ -30,40 +30,38 @@ interface ExtensionInterface * * @return callable[] */ - public function getNodeTranslators(); + public function getNodeTranslators(): array; /** * Returns combination translators. * * @return callable[] */ - public function getCombinationTranslators(); + public function getCombinationTranslators(): array; /** * Returns function translators. * * @return callable[] */ - public function getFunctionTranslators(); + public function getFunctionTranslators(): array; /** * Returns pseudo-class translators. * * @return callable[] */ - public function getPseudoClassTranslators(); + public function getPseudoClassTranslators(): array; /** * Returns attribute operation translators. * * @return callable[] */ - public function getAttributeMatchingTranslators(); + public function getAttributeMatchingTranslators(): array; /** * Returns extension name. - * - * @return string */ - public function getName(); + public function getName(): string; } diff --git a/vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php b/vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php index a121ab8cf..d3f7222a4 100644 --- a/vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php @@ -33,7 +33,7 @@ class FunctionExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getFunctionTranslators() + public function getFunctionTranslators(): array { return [ 'nth-child' => [$this, 'translateNthChild'], @@ -46,17 +46,12 @@ class FunctionExtension extends AbstractExtension } /** - * @param bool $last - * @param bool $addNameTest - * - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function translateNthChild(XPathExpr $xpath, FunctionNode $function, $last = false, $addNameTest = true) + public function translateNthChild(XPathExpr $xpath, FunctionNode $function, bool $last = false, bool $addNameTest = true): XPathExpr { try { - list($a, $b) = Parser::parseSeries($function->getArguments()); + [$a, $b] = Parser::parseSeries($function->getArguments()); } catch (SyntaxErrorException $e) { throw new ExpressionErrorException(sprintf('Invalid series: "%s".', implode('", "', $function->getArguments())), 0, $e); } @@ -108,28 +103,20 @@ class FunctionExtension extends AbstractExtension // -1n+6 means elements 6 and previous } - /** - * @return XPathExpr - */ - public function translateNthLastChild(XPathExpr $xpath, FunctionNode $function) + public function translateNthLastChild(XPathExpr $xpath, FunctionNode $function): XPathExpr { return $this->translateNthChild($xpath, $function, true); } - /** - * @return XPathExpr - */ - public function translateNthOfType(XPathExpr $xpath, FunctionNode $function) + public function translateNthOfType(XPathExpr $xpath, FunctionNode $function): XPathExpr { return $this->translateNthChild($xpath, $function, false, false); } /** - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function translateNthLastOfType(XPathExpr $xpath, FunctionNode $function) + public function translateNthLastOfType(XPathExpr $xpath, FunctionNode $function): XPathExpr { if ('*' === $xpath->getElement()) { throw new ExpressionErrorException('"*:nth-of-type()" is not implemented.'); @@ -139,11 +126,9 @@ class FunctionExtension extends AbstractExtension } /** - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function translateContains(XPathExpr $xpath, FunctionNode $function) + public function translateContains(XPathExpr $xpath, FunctionNode $function): XPathExpr { $arguments = $function->getArguments(); foreach ($arguments as $token) { @@ -159,11 +144,9 @@ class FunctionExtension extends AbstractExtension } /** - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function translateLang(XPathExpr $xpath, FunctionNode $function) + public function translateLang(XPathExpr $xpath, FunctionNode $function): XPathExpr { $arguments = $function->getArguments(); foreach ($arguments as $token) { @@ -181,7 +164,7 @@ class FunctionExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return 'function'; } diff --git a/vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php b/vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php index 99c1166c0..6edc08581 100644 --- a/vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php @@ -39,7 +39,7 @@ class HtmlExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getPseudoClassTranslators() + public function getPseudoClassTranslators(): array { return [ 'checked' => [$this, 'translateChecked'], @@ -56,17 +56,14 @@ class HtmlExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getFunctionTranslators() + public function getFunctionTranslators(): array { return [ 'lang' => [$this, 'translateLang'], ]; } - /** - * @return XPathExpr - */ - public function translateChecked(XPathExpr $xpath) + public function translateChecked(XPathExpr $xpath): XPathExpr { return $xpath->addCondition( '(@checked ' @@ -75,18 +72,12 @@ class HtmlExtension extends AbstractExtension ); } - /** - * @return XPathExpr - */ - public function translateLink(XPathExpr $xpath) + public function translateLink(XPathExpr $xpath): XPathExpr { return $xpath->addCondition("@href and (name(.) = 'a' or name(.) = 'link' or name(.) = 'area')"); } - /** - * @return XPathExpr - */ - public function translateDisabled(XPathExpr $xpath) + public function translateDisabled(XPathExpr $xpath): XPathExpr { return $xpath->addCondition( '(' @@ -112,10 +103,7 @@ class HtmlExtension extends AbstractExtension // todo: in the second half, add "and is not a descendant of that fieldset element's first legend element child, if any." } - /** - * @return XPathExpr - */ - public function translateEnabled(XPathExpr $xpath) + public function translateEnabled(XPathExpr $xpath): XPathExpr { return $xpath->addCondition( '(' @@ -149,11 +137,9 @@ class HtmlExtension extends AbstractExtension } /** - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function translateLang(XPathExpr $xpath, FunctionNode $function) + public function translateLang(XPathExpr $xpath, FunctionNode $function): XPathExpr { $arguments = $function->getArguments(); foreach ($arguments as $token) { @@ -171,34 +157,22 @@ class HtmlExtension extends AbstractExtension )); } - /** - * @return XPathExpr - */ - public function translateSelected(XPathExpr $xpath) + public function translateSelected(XPathExpr $xpath): XPathExpr { return $xpath->addCondition("(@selected and name(.) = 'option')"); } - /** - * @return XPathExpr - */ - public function translateInvalid(XPathExpr $xpath) + public function translateInvalid(XPathExpr $xpath): XPathExpr { return $xpath->addCondition('0'); } - /** - * @return XPathExpr - */ - public function translateHover(XPathExpr $xpath) + public function translateHover(XPathExpr $xpath): XPathExpr { return $xpath->addCondition('0'); } - /** - * @return XPathExpr - */ - public function translateVisited(XPathExpr $xpath) + public function translateVisited(XPathExpr $xpath): XPathExpr { return $xpath->addCondition('0'); } @@ -206,7 +180,7 @@ class HtmlExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return 'html'; } diff --git a/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php b/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php index de222af34..0e138229e 100644 --- a/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php @@ -27,27 +27,21 @@ use Symfony\Component\CssSelector\XPath\XPathExpr; */ class NodeExtension extends AbstractExtension { - const ELEMENT_NAME_IN_LOWER_CASE = 1; - const ATTRIBUTE_NAME_IN_LOWER_CASE = 2; - const ATTRIBUTE_VALUE_IN_LOWER_CASE = 4; + public const ELEMENT_NAME_IN_LOWER_CASE = 1; + public const ATTRIBUTE_NAME_IN_LOWER_CASE = 2; + public const ATTRIBUTE_VALUE_IN_LOWER_CASE = 4; private $flags; - /** - * @param int $flags - */ - public function __construct($flags = 0) + public function __construct(int $flags = 0) { $this->flags = $flags; } /** - * @param int $flag - * @param bool $on - * * @return $this */ - public function setFlag($flag, $on) + public function setFlag(int $flag, bool $on): self { if ($on && !$this->hasFlag($flag)) { $this->flags += $flag; @@ -60,12 +54,7 @@ class NodeExtension extends AbstractExtension return $this; } - /** - * @param int $flag - * - * @return bool - */ - public function hasFlag($flag) + public function hasFlag(int $flag): bool { return (bool) ($this->flags & $flag); } @@ -73,7 +62,7 @@ class NodeExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getNodeTranslators() + public function getNodeTranslators(): array { return [ 'Selector' => [$this, 'translateSelector'], @@ -88,26 +77,17 @@ class NodeExtension extends AbstractExtension ]; } - /** - * @return XPathExpr - */ - public function translateSelector(Node\SelectorNode $node, Translator $translator) + public function translateSelector(Node\SelectorNode $node, Translator $translator): XPathExpr { return $translator->nodeToXPath($node->getTree()); } - /** - * @return XPathExpr - */ - public function translateCombinedSelector(Node\CombinedSelectorNode $node, Translator $translator) + public function translateCombinedSelector(Node\CombinedSelectorNode $node, Translator $translator): XPathExpr { return $translator->addCombination($node->getCombinator(), $node->getSelector(), $node->getSubSelector()); } - /** - * @return XPathExpr - */ - public function translateNegation(Node\NegationNode $node, Translator $translator) + public function translateNegation(Node\NegationNode $node, Translator $translator): XPathExpr { $xpath = $translator->nodeToXPath($node->getSelector()); $subXpath = $translator->nodeToXPath($node->getSubSelector()); @@ -120,30 +100,21 @@ class NodeExtension extends AbstractExtension return $xpath->addCondition('0'); } - /** - * @return XPathExpr - */ - public function translateFunction(Node\FunctionNode $node, Translator $translator) + public function translateFunction(Node\FunctionNode $node, Translator $translator): XPathExpr { $xpath = $translator->nodeToXPath($node->getSelector()); return $translator->addFunction($xpath, $node); } - /** - * @return XPathExpr - */ - public function translatePseudo(Node\PseudoNode $node, Translator $translator) + public function translatePseudo(Node\PseudoNode $node, Translator $translator): XPathExpr { $xpath = $translator->nodeToXPath($node->getSelector()); return $translator->addPseudoClass($xpath, $node->getIdentifier()); } - /** - * @return XPathExpr - */ - public function translateAttribute(Node\AttributeNode $node, Translator $translator) + public function translateAttribute(Node\AttributeNode $node, Translator $translator): XPathExpr { $name = $node->getAttribute(); $safe = $this->isSafeName($name); @@ -168,30 +139,21 @@ class NodeExtension extends AbstractExtension return $translator->addAttributeMatching($xpath, $node->getOperator(), $attribute, $value); } - /** - * @return XPathExpr - */ - public function translateClass(Node\ClassNode $node, Translator $translator) + public function translateClass(Node\ClassNode $node, Translator $translator): XPathExpr { $xpath = $translator->nodeToXPath($node->getSelector()); return $translator->addAttributeMatching($xpath, '~=', '@class', $node->getName()); } - /** - * @return XPathExpr - */ - public function translateHash(Node\HashNode $node, Translator $translator) + public function translateHash(Node\HashNode $node, Translator $translator): XPathExpr { $xpath = $translator->nodeToXPath($node->getSelector()); return $translator->addAttributeMatching($xpath, '=', '@id', $node->getId()); } - /** - * @return XPathExpr - */ - public function translateElement(Node\ElementNode $node) + public function translateElement(Node\ElementNode $node): XPathExpr { $element = $node->getElement(); @@ -223,19 +185,12 @@ class NodeExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return 'node'; } - /** - * Tests if given name is safe. - * - * @param string $name - * - * @return bool - */ - private function isSafeName($name) + private function isSafeName(string $name): bool { return 0 < preg_match('~^[a-zA-Z_][a-zA-Z0-9_.-]*$~', $name); } diff --git a/vendor/symfony/css-selector/XPath/Extension/PseudoClassExtension.php b/vendor/symfony/css-selector/XPath/Extension/PseudoClassExtension.php index 288a9e695..a50b0486a 100644 --- a/vendor/symfony/css-selector/XPath/Extension/PseudoClassExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/PseudoClassExtension.php @@ -29,7 +29,7 @@ class PseudoClassExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getPseudoClassTranslators() + public function getPseudoClassTranslators(): array { return [ 'root' => [$this, 'translateRoot'], @@ -43,18 +43,12 @@ class PseudoClassExtension extends AbstractExtension ]; } - /** - * @return XPathExpr - */ - public function translateRoot(XPathExpr $xpath) + public function translateRoot(XPathExpr $xpath): XPathExpr { return $xpath->addCondition('not(parent::*)'); } - /** - * @return XPathExpr - */ - public function translateFirstChild(XPathExpr $xpath) + public function translateFirstChild(XPathExpr $xpath): XPathExpr { return $xpath ->addStarPrefix() @@ -62,10 +56,7 @@ class PseudoClassExtension extends AbstractExtension ->addCondition('position() = 1'); } - /** - * @return XPathExpr - */ - public function translateLastChild(XPathExpr $xpath) + public function translateLastChild(XPathExpr $xpath): XPathExpr { return $xpath ->addStarPrefix() @@ -74,11 +65,9 @@ class PseudoClassExtension extends AbstractExtension } /** - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function translateFirstOfType(XPathExpr $xpath) + public function translateFirstOfType(XPathExpr $xpath): XPathExpr { if ('*' === $xpath->getElement()) { throw new ExpressionErrorException('"*:first-of-type" is not implemented.'); @@ -90,11 +79,9 @@ class PseudoClassExtension extends AbstractExtension } /** - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function translateLastOfType(XPathExpr $xpath) + public function translateLastOfType(XPathExpr $xpath): XPathExpr { if ('*' === $xpath->getElement()) { throw new ExpressionErrorException('"*:last-of-type" is not implemented.'); @@ -105,10 +92,7 @@ class PseudoClassExtension extends AbstractExtension ->addCondition('position() = last()'); } - /** - * @return XPathExpr - */ - public function translateOnlyChild(XPathExpr $xpath) + public function translateOnlyChild(XPathExpr $xpath): XPathExpr { return $xpath ->addStarPrefix() @@ -116,26 +100,14 @@ class PseudoClassExtension extends AbstractExtension ->addCondition('last() = 1'); } - /** - * @return XPathExpr - * - * @throws ExpressionErrorException - */ - public function translateOnlyOfType(XPathExpr $xpath) + public function translateOnlyOfType(XPathExpr $xpath): XPathExpr { $element = $xpath->getElement(); - if ('*' === $element) { - throw new ExpressionErrorException('"*:only-of-type" is not implemented.'); - } - return $xpath->addCondition(sprintf('count(preceding-sibling::%s)=0 and count(following-sibling::%s)=0', $element, $element)); } - /** - * @return XPathExpr - */ - public function translateEmpty(XPathExpr $xpath) + public function translateEmpty(XPathExpr $xpath): XPathExpr { return $xpath->addCondition('not(*) and not(string-length())'); } @@ -143,7 +115,7 @@ class PseudoClassExtension extends AbstractExtension /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return 'pseudo-class'; } diff --git a/vendor/symfony/css-selector/XPath/Translator.php b/vendor/symfony/css-selector/XPath/Translator.php index 738886031..d1b65187e 100644 --- a/vendor/symfony/css-selector/XPath/Translator.php +++ b/vendor/symfony/css-selector/XPath/Translator.php @@ -61,12 +61,7 @@ class Translator implements TranslatorInterface ; } - /** - * @param string $element - * - * @return string - */ - public static function getXpathLiteral($element) + public static function getXpathLiteral(string $element): string { if (false === strpos($element, "'")) { return "'".$element."'"; @@ -95,7 +90,7 @@ class Translator implements TranslatorInterface /** * {@inheritdoc} */ - public function cssToXPath($cssExpr, $prefix = 'descendant-or-self::') + public function cssToXPath(string $cssExpr, string $prefix = 'descendant-or-self::'): string { $selectors = $this->parseSelectors($cssExpr); @@ -114,17 +109,15 @@ class Translator implements TranslatorInterface /** * {@inheritdoc} */ - public function selectorToXPath(SelectorNode $selector, $prefix = 'descendant-or-self::') + public function selectorToXPath(SelectorNode $selector, string $prefix = 'descendant-or-self::'): string { return ($prefix ?: '').$this->nodeToXPath($selector); } /** - * Registers an extension. - * * @return $this */ - public function registerExtension(Extension\ExtensionInterface $extension) + public function registerExtension(Extension\ExtensionInterface $extension): self { $this->extensions[$extension->getName()] = $extension; @@ -138,13 +131,9 @@ class Translator implements TranslatorInterface } /** - * @param string $name - * - * @return Extension\ExtensionInterface - * * @throws ExpressionErrorException */ - public function getExtension($name) + public function getExtension(string $name): Extension\ExtensionInterface { if (!isset($this->extensions[$name])) { throw new ExpressionErrorException(sprintf('Extension "%s" not registered.', $name)); @@ -154,11 +143,9 @@ class Translator implements TranslatorInterface } /** - * Registers a shortcut parser. - * * @return $this */ - public function registerParserShortcut(ParserInterface $shortcut) + public function registerParserShortcut(ParserInterface $shortcut): self { $this->shortcutParsers[] = $shortcut; @@ -166,89 +153,69 @@ class Translator implements TranslatorInterface } /** - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function nodeToXPath(NodeInterface $node) + public function nodeToXPath(NodeInterface $node): XPathExpr { if (!isset($this->nodeTranslators[$node->getNodeName()])) { throw new ExpressionErrorException(sprintf('Node "%s" not supported.', $node->getNodeName())); } - return \call_user_func($this->nodeTranslators[$node->getNodeName()], $node, $this); + return $this->nodeTranslators[$node->getNodeName()]($node, $this); } /** - * @param string $combiner - * - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function addCombination($combiner, NodeInterface $xpath, NodeInterface $combinedXpath) + public function addCombination(string $combiner, NodeInterface $xpath, NodeInterface $combinedXpath): XPathExpr { if (!isset($this->combinationTranslators[$combiner])) { throw new ExpressionErrorException(sprintf('Combiner "%s" not supported.', $combiner)); } - return \call_user_func($this->combinationTranslators[$combiner], $this->nodeToXPath($xpath), $this->nodeToXPath($combinedXpath)); + return $this->combinationTranslators[$combiner]($this->nodeToXPath($xpath), $this->nodeToXPath($combinedXpath)); } /** - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function addFunction(XPathExpr $xpath, FunctionNode $function) + public function addFunction(XPathExpr $xpath, FunctionNode $function): XPathExpr { if (!isset($this->functionTranslators[$function->getName()])) { throw new ExpressionErrorException(sprintf('Function "%s" not supported.', $function->getName())); } - return \call_user_func($this->functionTranslators[$function->getName()], $xpath, $function); + return $this->functionTranslators[$function->getName()]($xpath, $function); } /** - * @param string $pseudoClass - * - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function addPseudoClass(XPathExpr $xpath, $pseudoClass) + public function addPseudoClass(XPathExpr $xpath, string $pseudoClass): XPathExpr { if (!isset($this->pseudoClassTranslators[$pseudoClass])) { throw new ExpressionErrorException(sprintf('Pseudo-class "%s" not supported.', $pseudoClass)); } - return \call_user_func($this->pseudoClassTranslators[$pseudoClass], $xpath); + return $this->pseudoClassTranslators[$pseudoClass]($xpath); } /** - * @param string $operator - * @param string $attribute - * @param string $value - * - * @return XPathExpr - * * @throws ExpressionErrorException */ - public function addAttributeMatching(XPathExpr $xpath, $operator, $attribute, $value) + public function addAttributeMatching(XPathExpr $xpath, string $operator, string $attribute, $value): XPathExpr { if (!isset($this->attributeMatchingTranslators[$operator])) { throw new ExpressionErrorException(sprintf('Attribute matcher operator "%s" not supported.', $operator)); } - return \call_user_func($this->attributeMatchingTranslators[$operator], $xpath, $attribute, $value); + return $this->attributeMatchingTranslators[$operator]($xpath, $attribute, $value); } /** - * @param string $css - * * @return SelectorNode[] */ - private function parseSelectors($css) + private function parseSelectors(string $css): array { foreach ($this->shortcutParsers as $shortcut) { $tokens = $shortcut->parse($css); diff --git a/vendor/symfony/css-selector/XPath/TranslatorInterface.php b/vendor/symfony/css-selector/XPath/TranslatorInterface.php index fdbdf2255..c19eefb9c 100644 --- a/vendor/symfony/css-selector/XPath/TranslatorInterface.php +++ b/vendor/symfony/css-selector/XPath/TranslatorInterface.php @@ -27,20 +27,11 @@ interface TranslatorInterface { /** * Translates a CSS selector to an XPath expression. - * - * @param string $cssExpr - * @param string $prefix - * - * @return string */ - public function cssToXPath($cssExpr, $prefix = 'descendant-or-self::'); + public function cssToXPath(string $cssExpr, string $prefix = 'descendant-or-self::'): string; /** * Translates a parsed selector node to an XPath expression. - * - * @param string $prefix - * - * @return string */ - public function selectorToXPath(SelectorNode $selector, $prefix = 'descendant-or-self::'); + public function selectorToXPath(SelectorNode $selector, string $prefix = 'descendant-or-self::'): string; } diff --git a/vendor/symfony/css-selector/XPath/XPathExpr.php b/vendor/symfony/css-selector/XPath/XPathExpr.php index a1e244c9e..638cbd0fe 100644 --- a/vendor/symfony/css-selector/XPath/XPathExpr.php +++ b/vendor/symfony/css-selector/XPath/XPathExpr.php @@ -27,13 +27,7 @@ class XPathExpr private $element; private $condition; - /** - * @param string $path - * @param string $element - * @param string $condition - * @param bool $starPrefix - */ - public function __construct($path = '', $element = '*', $condition = '', $starPrefix = false) + public function __construct(string $path = '', string $element = '*', string $condition = '', bool $starPrefix = false) { $this->path = $path; $this->element = $element; @@ -44,36 +38,24 @@ class XPathExpr } } - /** - * @return string - */ - public function getElement() + public function getElement(): string { return $this->element; } - /** - * @return $this - */ - public function addCondition($condition) + public function addCondition(string $condition): self { $this->condition = $this->condition ? sprintf('(%s) and (%s)', $this->condition, $condition) : $condition; return $this; } - /** - * @return string - */ - public function getCondition() + public function getCondition(): string { return $this->condition; } - /** - * @return $this - */ - public function addNameTest() + public function addNameTest(): self { if ('*' !== $this->element) { $this->addCondition('name() = '.Translator::getXpathLiteral($this->element)); @@ -83,10 +65,7 @@ class XPathExpr return $this; } - /** - * @return $this - */ - public function addStarPrefix() + public function addStarPrefix(): self { $this->path .= '*/'; @@ -96,12 +75,9 @@ class XPathExpr /** * Joins another XPathExpr with a combiner. * - * @param string $combiner - * @param XPathExpr $expr - * * @return $this */ - public function join($combiner, self $expr) + public function join(string $combiner, self $expr): self { $path = $this->__toString().$combiner; @@ -116,10 +92,7 @@ class XPathExpr return $this; } - /** - * @return string - */ - public function __toString() + public function __toString(): string { $path = $this->path.$this->element; $condition = null === $this->condition || '' === $this->condition ? '' : '['.$this->condition.']'; diff --git a/vendor/symfony/css-selector/composer.json b/vendor/symfony/css-selector/composer.json index 435063fd4..eb63cf59c 100644 --- a/vendor/symfony/css-selector/composer.json +++ b/vendor/symfony/css-selector/composer.json @@ -1,7 +1,7 @@ { "name": "symfony/css-selector", "type": "library", - "description": "Symfony CssSelector Component", + "description": "Converts CSS selectors to XPath expressions", "keywords": [], "homepage": "https://symfony.com", "license": "MIT", @@ -20,7 +20,7 @@ } ], "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=7.2.5" }, "autoload": { "psr-4": { "Symfony\\Component\\CssSelector\\": "" }, diff --git a/vendor/symfony/event-dispatcher/CHANGELOG.md b/vendor/symfony/event-dispatcher/CHANGELOG.md index c6aa5389a..54fd04227 100644 --- a/vendor/symfony/event-dispatcher/CHANGELOG.md +++ b/vendor/symfony/event-dispatcher/CHANGELOG.md @@ -1,6 +1,31 @@ CHANGELOG ========= +4.4.0 +----- + + * `AddEventAliasesPass` has been added, allowing applications and bundles to extend the event alias mapping used by `RegisterListenersPass`. + * Made the `event` attribute of the `kernel.event_listener` tag optional for FQCN events. + +4.3.0 +----- + + * The signature of the `EventDispatcherInterface::dispatch()` method should be updated to `dispatch($event, string $eventName = null)`, not doing so is deprecated + * deprecated the `Event` class, use `Symfony\Contracts\EventDispatcher\Event` instead + +4.1.0 +----- + + * added support for invokable event listeners tagged with `kernel.event_listener` by default + * The `TraceableEventDispatcher::getOrphanedEvents()` method has been added. + * The `TraceableEventDispatcherInterface` has been deprecated. + +4.0.0 +----- + + * removed the `ContainerAwareEventDispatcher` class + * added the `reset()` method to the `TraceableEventDispatcherInterface` + 3.4.0 ----- diff --git a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php index 017459723..e79d1a8e3 100644 --- a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php +++ b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php @@ -11,11 +11,17 @@ namespace Symfony\Component\EventDispatcher\Debug; +use Psr\EventDispatcher\StoppableEventInterface; use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy; +use Symfony\Component\EventDispatcher\LegacyEventProxy; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Contracts\EventDispatcher\Event as ContractsEvent; /** * Collects some data about event listeners. @@ -32,13 +38,18 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface private $callStack; private $dispatcher; private $wrappedListeners; + private $orphanedEvents; + private $requestStack; + private $currentRequestHash = ''; - public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null) + public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null, RequestStack $requestStack = null) { - $this->dispatcher = $dispatcher; + $this->dispatcher = LegacyEventDispatcherProxy::decorate($dispatcher); $this->stopwatch = $stopwatch; $this->logger = $logger; $this->wrappedListeners = []; + $this->orphanedEvents = []; + $this->requestStack = $requestStack; } /** @@ -119,37 +130,52 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface /** * {@inheritdoc} + * + * @param string|null $eventName */ - public function dispatch($eventName, Event $event = null) + public function dispatch($event/*, string $eventName = null*/) { if (null === $this->callStack) { $this->callStack = new \SplObjectStorage(); } - if (null === $event) { - $event = new Event(); + $currentRequestHash = $this->currentRequestHash = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_hash($request) : ''; + $eventName = 1 < \func_num_args() ? func_get_arg(1) : null; + + if (\is_object($event)) { + $eventName = $eventName ?? \get_class($event); + } else { + @trigger_error(sprintf('Calling the "%s::dispatch()" method with the event name as first argument is deprecated since Symfony 4.3, pass it second and provide the event object first instead.', EventDispatcherInterface::class), \E_USER_DEPRECATED); + $swap = $event; + $event = $eventName ?? new Event(); + $eventName = $swap; + + if (!$event instanceof Event) { + throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an instance of "%s", "%s" given.', EventDispatcherInterface::class, Event::class, \is_object($event) ? \get_class($event) : \gettype($event))); + } } - if (null !== $this->logger && $event->isPropagationStopped()) { + if (null !== $this->logger && ($event instanceof Event || $event instanceof ContractsEvent || $event instanceof StoppableEventInterface) && $event->isPropagationStopped()) { $this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName)); } $this->preProcess($eventName); try { - $this->preDispatch($eventName, $event); + $this->beforeDispatch($eventName, $event); try { $e = $this->stopwatch->start($eventName, 'section'); try { - $this->dispatcher->dispatch($eventName, $event); + $this->dispatcher->dispatch($event, $eventName); } finally { if ($e->isStarted()) { $e->stop(); } } } finally { - $this->postDispatch($eventName, $event); + $this->afterDispatch($eventName, $event); } } finally { + $this->currentRequestHash = $currentRequestHash; $this->postProcess($eventName); } @@ -158,18 +184,22 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface /** * {@inheritdoc} + * + * @param Request|null $request The request to get listeners for */ - public function getCalledListeners() + public function getCalledListeners(/* Request $request = null */) { if (null === $this->callStack) { return []; } + $hash = 1 <= \func_num_args() && null !== ($request = func_get_arg(0)) ? spl_object_hash($request) : null; $called = []; foreach ($this->callStack as $listener) { - list($eventName) = $this->callStack->getInfo(); - - $called[] = $listener->getInfo($eventName); + [$eventName, $requestHash] = $this->callStack->getInfo(); + if (null === $hash || $hash === $requestHash) { + $called[] = $listener->getInfo($eventName); + } } return $called; @@ -177,8 +207,10 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface /** * {@inheritdoc} + * + * @param Request|null $request The request to get listeners for */ - public function getNotCalledListeners() + public function getNotCalledListeners(/* Request $request = null */) { try { $allListeners = $this->getListeners(); @@ -191,11 +223,16 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface return []; } + $hash = 1 <= \func_num_args() && null !== ($request = func_get_arg(0)) ? spl_object_hash($request) : null; $calledListeners = []; if (null !== $this->callStack) { foreach ($this->callStack as $calledListener) { - $calledListeners[] = $calledListener->getWrappedListener(); + [, $requestHash] = $this->callStack->getInfo(); + + if (null === $hash || $hash === $requestHash) { + $calledListeners[] = $calledListener->getWrappedListener(); + } } } @@ -216,9 +253,27 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface return $notCalled; } + /** + * @param Request|null $request The request to get orphaned events for + */ + public function getOrphanedEvents(/* Request $request = null */): array + { + if (1 <= \func_num_args() && null !== $request = func_get_arg(0)) { + return $this->orphanedEvents[spl_object_hash($request)] ?? []; + } + + if (!$this->orphanedEvents) { + return []; + } + + return array_merge(...array_values($this->orphanedEvents)); + } + public function reset() { $this->callStack = null; + $this->orphanedEvents = []; + $this->currentRequestHash = ''; } /** @@ -231,42 +286,62 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface */ public function __call($method, $arguments) { - return \call_user_func_array([$this->dispatcher, $method], $arguments); + return $this->dispatcher->{$method}(...$arguments); } /** * Called before dispatching the event. * - * @param string $eventName The event name - * @param Event $event The event + * @param object $event + */ + protected function beforeDispatch(string $eventName, $event) + { + $this->preDispatch($eventName, $event instanceof Event ? $event : new LegacyEventProxy($event)); + } + + /** + * Called after dispatching the event. + * + * @param object $event + */ + protected function afterDispatch(string $eventName, $event) + { + $this->postDispatch($eventName, $event instanceof Event ? $event : new LegacyEventProxy($event)); + } + + /** + * @deprecated since Symfony 4.3, will be removed in 5.0, use beforeDispatch instead */ protected function preDispatch($eventName, Event $event) { } /** - * Called after dispatching the event. - * - * @param string $eventName The event name - * @param Event $event The event + * @deprecated since Symfony 4.3, will be removed in 5.0, use afterDispatch instead */ protected function postDispatch($eventName, Event $event) { } - private function preProcess($eventName) + private function preProcess(string $eventName) { + if (!$this->dispatcher->hasListeners($eventName)) { + $this->orphanedEvents[$this->currentRequestHash][] = $eventName; + + return; + } + foreach ($this->dispatcher->getListeners($eventName) as $listener) { $priority = $this->getListenerPriority($eventName, $listener); $wrappedListener = new WrappedListener($listener instanceof WrappedListener ? $listener->getWrappedListener() : $listener, null, $this->stopwatch, $this); $this->wrappedListeners[$eventName][] = $wrappedListener; $this->dispatcher->removeListener($eventName, $listener); $this->dispatcher->addListener($eventName, $wrappedListener, $priority); - $this->callStack->attach($wrappedListener, [$eventName]); + $this->callStack->attach($wrappedListener, [$eventName, $this->currentRequestHash]); } } - private function postProcess($eventName) + private function postProcess(string $eventName) { unset($this->wrappedListeners[$eventName]); $skipped = false; diff --git a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php index f0212753b..4fedb9a41 100644 --- a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php +++ b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php @@ -12,25 +12,31 @@ namespace Symfony\Component\EventDispatcher\Debug; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Contracts\Service\ResetInterface; /** - * @author Fabien Potencier + * @deprecated since Symfony 4.1 * - * @method reset() Resets the trace. + * @author Fabien Potencier */ -interface TraceableEventDispatcherInterface extends EventDispatcherInterface +interface TraceableEventDispatcherInterface extends EventDispatcherInterface, ResetInterface { /** * Gets the called listeners. * + * @param Request|null $request The request to get listeners for + * * @return array An array of called listeners */ - public function getCalledListeners(); + public function getCalledListeners(/* Request $request = null */); /** * Gets the not called listeners. * + * @param Request|null $request The request to get listeners for + * * @return array An array of not called listeners */ - public function getNotCalledListeners(); + public function getNotCalledListeners(/* Request $request = null */); } diff --git a/vendor/symfony/event-dispatcher/Debug/WrappedListener.php b/vendor/symfony/event-dispatcher/Debug/WrappedListener.php index de2b85095..e04763908 100644 --- a/vendor/symfony/event-dispatcher/Debug/WrappedListener.php +++ b/vendor/symfony/event-dispatcher/Debug/WrappedListener.php @@ -11,17 +11,23 @@ namespace Symfony\Component\EventDispatcher\Debug; +use Psr\EventDispatcher\StoppableEventInterface; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\LegacyEventProxy; use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Component\VarDumper\Caster\ClassStub; +use Symfony\Contracts\EventDispatcher\Event as ContractsEvent; /** * @author Fabien Potencier + * + * @final since Symfony 4.3: the "Event" type-hint on __invoke() will be replaced by "object" in 5.0 */ class WrappedListener { private $listener; + private $optimizedListener; private $name; private $called; private $stoppedPropagation; @@ -32,9 +38,10 @@ class WrappedListener private $priority; private static $hasClassStub; - public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null) + public function __construct($listener, ?string $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null) { $this->listener = $listener; + $this->optimizedListener = $listener instanceof \Closure ? $listener : (\is_callable($listener) ? \Closure::fromCallable($listener) : null); $this->stopwatch = $stopwatch; $this->dispatcher = $dispatcher; $this->called = false; @@ -105,6 +112,10 @@ class WrappedListener public function __invoke(Event $event, $eventName, EventDispatcherInterface $dispatcher) { + if ($event instanceof LegacyEventProxy) { + $event = $event->getEvent(); + } + $dispatcher = $this->dispatcher ?: $dispatcher; $this->called = true; @@ -112,13 +123,13 @@ class WrappedListener $e = $this->stopwatch->start($this->name, 'event_listener'); - \call_user_func($this->listener, $event, $eventName, $dispatcher); + ($this->optimizedListener ?? $this->listener)($event, $eventName, $dispatcher); if ($e->isStarted()) { $e->stop(); } - if ($event->isPropagationStopped()) { + if (($event instanceof Event || $event instanceof ContractsEvent || $event instanceof StoppableEventInterface) && $event->isPropagationStopped()) { $this->stoppedPropagation = true; } } diff --git a/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php b/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php index 2951c1ee4..1a52c3e86 100644 --- a/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php +++ b/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php @@ -16,8 +16,10 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\EventDispatcher\Event as LegacyEvent; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Contracts\EventDispatcher\Event; /** * Compiler pass to register tagged services for an event dispatcher. @@ -27,20 +29,17 @@ class RegisterListenersPass implements CompilerPassInterface protected $dispatcherService; protected $listenerTag; protected $subscriberTag; + protected $eventAliasesParameter; private $hotPathEvents = []; private $hotPathTagName; - /** - * @param string $dispatcherService Service name of the event dispatcher in processed container - * @param string $listenerTag Tag name used for listener - * @param string $subscriberTag Tag name used for subscribers - */ - public function __construct($dispatcherService = 'event_dispatcher', $listenerTag = 'kernel.event_listener', $subscriberTag = 'kernel.event_subscriber') + public function __construct(string $dispatcherService = 'event_dispatcher', string $listenerTag = 'kernel.event_listener', string $subscriberTag = 'kernel.event_subscriber', string $eventAliasesParameter = 'event_dispatcher.event_aliases') { $this->dispatcherService = $dispatcherService; $this->listenerTag = $listenerTag; $this->subscriberTag = $subscriberTag; + $this->eventAliasesParameter = $eventAliasesParameter; } public function setHotPathEvents(array $hotPathEvents, $tagName = 'container.hot_path') @@ -57,22 +56,39 @@ class RegisterListenersPass implements CompilerPassInterface return; } + $aliases = []; + + if ($container->hasParameter($this->eventAliasesParameter)) { + $aliases = $container->getParameter($this->eventAliasesParameter); + } + $definition = $container->findDefinition($this->dispatcherService); foreach ($container->findTaggedServiceIds($this->listenerTag, true) as $id => $events) { foreach ($events as $event) { - $priority = isset($event['priority']) ? $event['priority'] : 0; + $priority = $event['priority'] ?? 0; if (!isset($event['event'])) { - throw new InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "%s" tags.', $id, $this->listenerTag)); + if ($container->getDefinition($id)->hasTag($this->subscriberTag)) { + continue; + } + + $event['method'] = $event['method'] ?? '__invoke'; + $event['event'] = $this->getEventFromTypeDeclaration($container, $id, $event['method']); } + $event['event'] = $aliases[$event['event']] ?? $event['event']; + if (!isset($event['method'])) { $event['method'] = 'on'.preg_replace_callback([ '/(?<=\b)[a-z]/i', '/[^a-z0-9]/i', ], function ($matches) { return strtoupper($matches[0]); }, $event['event']); $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']); + + if (null !== ($class = $container->getDefinition($id)->getClass()) && ($r = $container->getReflectionClass($class, false)) && !$r->hasMethod($event['method']) && $r->hasMethod('__invoke')) { + $event['method'] = '__invoke'; + } } $definition->addMethodCall('addListener', [$event['event'], [new ServiceClosureArgument(new Reference($id)), $event['method']], $priority]); @@ -99,6 +115,7 @@ class RegisterListenersPass implements CompilerPassInterface } $class = $r->name; + ExtractingEventDispatcher::$aliases = $aliases; ExtractingEventDispatcher::$subscriber = $class; $extractingDispatcher->addSubscriber($extractingDispatcher); foreach ($extractingDispatcher->listeners as $args) { @@ -110,8 +127,27 @@ class RegisterListenersPass implements CompilerPassInterface } } $extractingDispatcher->listeners = []; + ExtractingEventDispatcher::$aliases = []; } } + + private function getEventFromTypeDeclaration(ContainerBuilder $container, string $id, string $method): string + { + if ( + null === ($class = $container->getDefinition($id)->getClass()) + || !($r = $container->getReflectionClass($class, false)) + || !$r->hasMethod($method) + || 1 > ($m = $r->getMethod($method))->getNumberOfParameters() + || !($type = $m->getParameters()[0]->getType()) instanceof \ReflectionNamedType + || $type->isBuiltin() + || Event::class === ($name = $type->getName()) + || LegacyEvent::class === $name + ) { + throw new InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "%s" tags.', $id, $this->listenerTag)); + } + + return $name; + } } /** @@ -121,6 +157,7 @@ class ExtractingEventDispatcher extends EventDispatcher implements EventSubscrib { public $listeners = []; + public static $aliases = []; public static $subscriber; public function addListener($eventName, $listener, $priority = 0) @@ -128,10 +165,14 @@ class ExtractingEventDispatcher extends EventDispatcher implements EventSubscrib $this->listeners[] = [$eventName, $listener[1], $priority]; } - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { - $callback = [self::$subscriber, 'getSubscribedEvents']; + $events = []; - return $callback(); + foreach ([self::$subscriber, 'getSubscribedEvents']() as $eventName => $params) { + $events[self::$aliases[$eventName] ?? $eventName] = $params; + } + + return $events; } } diff --git a/vendor/symfony/event-dispatcher/Event.php b/vendor/symfony/event-dispatcher/Event.php index 9c56b2f55..307c4be5d 100644 --- a/vendor/symfony/event-dispatcher/Event.php +++ b/vendor/symfony/event-dispatcher/Event.php @@ -12,32 +12,16 @@ namespace Symfony\Component\EventDispatcher; /** - * Event is the base class for classes containing event data. - * - * This class contains no event data. It is used by events that do not pass - * state information to an event handler when an event is raised. - * - * You can call the method stopPropagation() to abort the execution of - * further listeners in your event listener. - * - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author Bernhard Schussek + * @deprecated since Symfony 4.3, use "Symfony\Contracts\EventDispatcher\Event" instead */ class Event { - /** - * @var bool Whether no further event listeners should be triggered - */ private $propagationStopped = false; /** - * Returns whether further event listeners should be triggered. - * - * @see Event::stopPropagation() - * * @return bool Whether propagation was already stopped for this event + * + * @deprecated since Symfony 4.3, use "Symfony\Contracts\EventDispatcher\Event" instead */ public function isPropagationStopped() { @@ -45,11 +29,7 @@ class Event } /** - * Stops the propagation of the event to further event listeners. - * - * If multiple event listeners are connected to the same event, no - * further event listener will be triggered once any trigger calls - * stopPropagation(). + * @deprecated since Symfony 4.3, use "Symfony\Contracts\EventDispatcher\Event" instead */ public function stopPropagation() { diff --git a/vendor/symfony/event-dispatcher/EventDispatcher.php b/vendor/symfony/event-dispatcher/EventDispatcher.php index 207790f06..8b6222718 100644 --- a/vendor/symfony/event-dispatcher/EventDispatcher.php +++ b/vendor/symfony/event-dispatcher/EventDispatcher.php @@ -11,6 +11,10 @@ namespace Symfony\Component\EventDispatcher; +use Psr\EventDispatcher\StoppableEventInterface; +use Symfony\Component\EventDispatcher\Debug\WrappedListener; +use Symfony\Contracts\EventDispatcher\Event as ContractsEvent; + /** * The EventDispatcherInterface is the central point of Symfony's event listener system. * @@ -30,18 +34,43 @@ class EventDispatcher implements EventDispatcherInterface { private $listeners = []; private $sorted = []; + private $optimized; + + public function __construct() + { + if (__CLASS__ === static::class) { + $this->optimized = []; + } + } /** * {@inheritdoc} + * + * @param string|null $eventName */ - public function dispatch($eventName, Event $event = null) + public function dispatch($event/*, string $eventName = null*/) { - if (null === $event) { - $event = new Event(); + $eventName = 1 < \func_num_args() ? func_get_arg(1) : null; + + if (\is_object($event)) { + $eventName = $eventName ?? \get_class($event); + } elseif (\is_string($event) && (null === $eventName || $eventName instanceof ContractsEvent || $eventName instanceof Event)) { + @trigger_error(sprintf('Calling the "%s::dispatch()" method with the event name as the first argument is deprecated since Symfony 4.3, pass it as the second argument and provide the event object as the first argument instead.', EventDispatcherInterface::class), \E_USER_DEPRECATED); + $swap = $event; + $event = $eventName ?? new Event(); + $eventName = $swap; + } else { + throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an object, "%s" given.', EventDispatcherInterface::class, \is_object($event) ? \get_class($event) : \gettype($event))); } - if ($listeners = $this->getListeners($eventName)) { - $this->doDispatch($listeners, $eventName, $event); + if (null !== $this->optimized && null !== $eventName) { + $listeners = $this->optimized[$eventName] ?? (empty($this->listeners[$eventName]) ? [] : $this->optimizeListeners($eventName)); + } else { + $listeners = $this->getListeners($eventName); + } + + if ($listeners) { + $this->callListeners($listeners, $eventName, $event); } return $event; @@ -82,15 +111,16 @@ class EventDispatcher implements EventDispatcherInterface return null; } - if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) { + if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) { $listener[0] = $listener[0](); + $listener[1] = $listener[1] ?? '__invoke'; } - foreach ($this->listeners[$eventName] as $priority => $listeners) { - foreach ($listeners as $k => $v) { - if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) { + foreach ($this->listeners[$eventName] as $priority => &$listeners) { + foreach ($listeners as &$v) { + if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure && 2 >= \count($v)) { $v[0] = $v[0](); - $this->listeners[$eventName][$priority][$k] = $v; + $v[1] = $v[1] ?? '__invoke'; } if ($v === $listener) { return $priority; @@ -125,7 +155,7 @@ class EventDispatcher implements EventDispatcherInterface public function addListener($eventName, $listener, $priority = 0) { $this->listeners[$eventName][$priority][] = $listener; - unset($this->sorted[$eventName]); + unset($this->sorted[$eventName], $this->optimized[$eventName]); } /** @@ -137,25 +167,23 @@ class EventDispatcher implements EventDispatcherInterface return; } - if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) { + if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) { $listener[0] = $listener[0](); + $listener[1] = $listener[1] ?? '__invoke'; } - foreach ($this->listeners[$eventName] as $priority => $listeners) { - foreach ($listeners as $k => $v) { - if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) { + foreach ($this->listeners[$eventName] as $priority => &$listeners) { + foreach ($listeners as $k => &$v) { + if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure && 2 >= \count($v)) { $v[0] = $v[0](); + $v[1] = $v[1] ?? '__invoke'; } if ($v === $listener) { - unset($listeners[$k], $this->sorted[$eventName]); - } else { - $listeners[$k] = $v; + unset($listeners[$k], $this->sorted[$eventName], $this->optimized[$eventName]); } } - if ($listeners) { - $this->listeners[$eventName][$priority] = $listeners; - } else { + if (!$listeners) { unset($this->listeners[$eventName][$priority]); } } @@ -170,10 +198,10 @@ class EventDispatcher implements EventDispatcherInterface if (\is_string($params)) { $this->addListener($eventName, [$subscriber, $params]); } elseif (\is_string($params[0])) { - $this->addListener($eventName, [$subscriber, $params[0]], isset($params[1]) ? $params[1] : 0); + $this->addListener($eventName, [$subscriber, $params[0]], $params[1] ?? 0); } else { foreach ($params as $listener) { - $this->addListener($eventName, [$subscriber, $listener[0]], isset($listener[1]) ? $listener[1] : 0); + $this->addListener($eventName, [$subscriber, $listener[0]], $listener[1] ?? 0); } } } @@ -203,7 +231,29 @@ class EventDispatcher implements EventDispatcherInterface * * @param callable[] $listeners The event listeners * @param string $eventName The name of the event to dispatch - * @param Event $event The event object to pass to the event handlers/listeners + * @param object $event The event object to pass to the event handlers/listeners + */ + protected function callListeners(iterable $listeners, string $eventName, $event) + { + if ($event instanceof Event) { + $this->doDispatch($listeners, $eventName, $event); + + return; + } + + $stoppable = $event instanceof ContractsEvent || $event instanceof StoppableEventInterface; + + foreach ($listeners as $listener) { + if ($stoppable && $event->isPropagationStopped()) { + break; + } + // @deprecated: the ternary operator is part of a BC layer and should be removed in 5.0 + $listener($listener instanceof WrappedListener ? new LegacyEventProxy($event) : $event, $eventName, $this); + } + } + + /** + * @deprecated since Symfony 4.3, use callListeners() instead */ protected function doDispatch($listeners, $eventName, Event $event) { @@ -211,28 +261,54 @@ class EventDispatcher implements EventDispatcherInterface if ($event->isPropagationStopped()) { break; } - \call_user_func($listener, $event, $eventName, $this); + $listener($event, $eventName, $this); } } /** * Sorts the internal list of listeners for the given event by priority. - * - * @param string $eventName The name of the event */ - private function sortListeners($eventName) + private function sortListeners(string $eventName) { krsort($this->listeners[$eventName]); $this->sorted[$eventName] = []; - foreach ($this->listeners[$eventName] as $priority => $listeners) { - foreach ($listeners as $k => $listener) { - if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) { + foreach ($this->listeners[$eventName] as &$listeners) { + foreach ($listeners as $k => &$listener) { + if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) { $listener[0] = $listener[0](); - $this->listeners[$eventName][$priority][$k] = $listener; + $listener[1] = $listener[1] ?? '__invoke'; } $this->sorted[$eventName][] = $listener; } } } + + /** + * Optimizes the internal list of listeners for the given event by priority. + */ + private function optimizeListeners(string $eventName): array + { + krsort($this->listeners[$eventName]); + $this->optimized[$eventName] = []; + + foreach ($this->listeners[$eventName] as &$listeners) { + foreach ($listeners as &$listener) { + $closure = &$this->optimized[$eventName][]; + if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) { + $closure = static function (...$args) use (&$listener, &$closure) { + if ($listener[0] instanceof \Closure) { + $listener[0] = $listener[0](); + $listener[1] = $listener[1] ?? '__invoke'; + } + ($closure = \Closure::fromCallable($listener))(...$args); + }; + } else { + $closure = $listener instanceof \Closure || $listener instanceof WrappedListener ? $listener : \Closure::fromCallable($listener); + } + } + } + + return $this->optimized[$eventName]; + } } diff --git a/vendor/symfony/event-dispatcher/EventDispatcherInterface.php b/vendor/symfony/event-dispatcher/EventDispatcherInterface.php index bde753a12..ceaa62aeb 100644 --- a/vendor/symfony/event-dispatcher/EventDispatcherInterface.php +++ b/vendor/symfony/event-dispatcher/EventDispatcherInterface.php @@ -11,6 +11,8 @@ namespace Symfony\Component\EventDispatcher; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as ContractsEventDispatcherInterface; + /** * The EventDispatcherInterface is the central point of Symfony's event listener system. * Listeners are registered on the manager and events are dispatched through the @@ -18,21 +20,8 @@ namespace Symfony\Component\EventDispatcher; * * @author Bernhard Schussek */ -interface EventDispatcherInterface +interface EventDispatcherInterface extends ContractsEventDispatcherInterface { - /** - * Dispatches an event to all registered listeners. - * - * @param string $eventName The name of the event to dispatch. The name of - * the event is the name of the method that is - * invoked on listeners. - * @param Event|null $event The event to pass to the event handlers/listeners - * If not supplied, an empty Event instance is created - * - * @return Event - */ - public function dispatch($eventName, Event $event = null); - /** * Adds an event listener that listens on the specified events. * diff --git a/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php b/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php index b3cf56c50..75a7d7318 100644 --- a/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php +++ b/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php @@ -22,15 +22,26 @@ class ImmutableEventDispatcher implements EventDispatcherInterface public function __construct(EventDispatcherInterface $dispatcher) { - $this->dispatcher = $dispatcher; + $this->dispatcher = LegacyEventDispatcherProxy::decorate($dispatcher); } /** * {@inheritdoc} + * + * @param string|null $eventName */ - public function dispatch($eventName, Event $event = null) + public function dispatch($event/*, string $eventName = null*/) { - return $this->dispatcher->dispatch($eventName, $event); + $eventName = 1 < \func_num_args() ? func_get_arg(1) : null; + + if (is_scalar($event)) { + // deprecated + $swap = $event; + $event = $eventName ?? new Event(); + $eventName = $swap; + } + + return $this->dispatcher->dispatch($event, $eventName); } /** diff --git a/vendor/symfony/event-dispatcher/LICENSE b/vendor/symfony/event-dispatcher/LICENSE index 9e936ec04..9ff2d0d63 100644 --- a/vendor/symfony/event-dispatcher/LICENSE +++ b/vendor/symfony/event-dispatcher/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2020 Fabien Potencier +Copyright (c) 2004-2021 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 diff --git a/vendor/symfony/event-dispatcher/composer.json b/vendor/symfony/event-dispatcher/composer.json index 408022f6b..8f6b5cefa 100644 --- a/vendor/symfony/event-dispatcher/composer.json +++ b/vendor/symfony/event-dispatcher/composer.json @@ -1,7 +1,7 @@ { "name": "symfony/event-dispatcher", "type": "library", - "description": "Symfony EventDispatcher Component", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "keywords": [], "homepage": "https://symfony.com", "license": "MIT", @@ -16,18 +16,25 @@ } ], "require": { - "php": "^5.5.9|>=7.0.8" + "php": ">=7.1.3", + "symfony/event-dispatcher-contracts": "^1.1" }, "require-dev": { - "symfony/dependency-injection": "~3.3|~4.0", - "symfony/expression-language": "~2.8|~3.0|~4.0", - "symfony/config": "~2.8|~3.0|~4.0", - "symfony/debug": "~3.4|~4.4", - "symfony/stopwatch": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/error-handler": "~3.4|~4.4", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/stopwatch": "^3.4|^4.0|^5.0", "psr/log": "~1.0" }, "conflict": { - "symfony/dependency-injection": "<3.3" + "symfony/dependency-injection": "<3.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "1.1" }, "suggest": { "symfony/dependency-injection": "", diff --git a/vendor/symfony/finder/Finder.php b/vendor/symfony/finder/Finder.php index 3e8a9483e..186cb3229 100644 --- a/vendor/symfony/finder/Finder.php +++ b/vendor/symfony/finder/Finder.php @@ -616,7 +616,7 @@ class Finder implements \IteratorAggregate, \Countable } /** - * Check if the any results were found. + * Check if any results were found. * * @return bool */ diff --git a/vendor/symfony/http-kernel/Kernel.php b/vendor/symfony/http-kernel/Kernel.php index 95eb438d4..280401e91 100644 --- a/vendor/symfony/http-kernel/Kernel.php +++ b/vendor/symfony/http-kernel/Kernel.php @@ -67,11 +67,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.46'; - const VERSION_ID = 30446; + const VERSION = '3.4.47'; + const VERSION_ID = 30447; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; - const RELEASE_VERSION = 46; + const RELEASE_VERSION = 47; const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2020'; diff --git a/vendor/symfony/polyfill-ctype/bootstrap.php b/vendor/symfony/polyfill-ctype/bootstrap.php index 0bc45cfdf..d54524b31 100644 --- a/vendor/symfony/polyfill-ctype/bootstrap.php +++ b/vendor/symfony/polyfill-ctype/bootstrap.php @@ -11,36 +11,40 @@ use Symfony\Polyfill\Ctype as p; +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + if (!function_exists('ctype_alnum')) { - function ctype_alnum($input) { return p\Ctype::ctype_alnum($input); } + function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); } } if (!function_exists('ctype_alpha')) { - function ctype_alpha($input) { return p\Ctype::ctype_alpha($input); } + function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); } } if (!function_exists('ctype_cntrl')) { - function ctype_cntrl($input) { return p\Ctype::ctype_cntrl($input); } + function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); } } if (!function_exists('ctype_digit')) { - function ctype_digit($input) { return p\Ctype::ctype_digit($input); } + function ctype_digit($text) { return p\Ctype::ctype_digit($text); } } if (!function_exists('ctype_graph')) { - function ctype_graph($input) { return p\Ctype::ctype_graph($input); } + function ctype_graph($text) { return p\Ctype::ctype_graph($text); } } if (!function_exists('ctype_lower')) { - function ctype_lower($input) { return p\Ctype::ctype_lower($input); } + function ctype_lower($text) { return p\Ctype::ctype_lower($text); } } if (!function_exists('ctype_print')) { - function ctype_print($input) { return p\Ctype::ctype_print($input); } + function ctype_print($text) { return p\Ctype::ctype_print($text); } } if (!function_exists('ctype_punct')) { - function ctype_punct($input) { return p\Ctype::ctype_punct($input); } + function ctype_punct($text) { return p\Ctype::ctype_punct($text); } } if (!function_exists('ctype_space')) { - function ctype_space($input) { return p\Ctype::ctype_space($input); } + function ctype_space($text) { return p\Ctype::ctype_space($text); } } if (!function_exists('ctype_upper')) { - function ctype_upper($input) { return p\Ctype::ctype_upper($input); } + function ctype_upper($text) { return p\Ctype::ctype_upper($text); } } if (!function_exists('ctype_xdigit')) { - function ctype_xdigit($input) { return p\Ctype::ctype_xdigit($input); } + function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); } } diff --git a/vendor/symfony/polyfill-ctype/composer.json b/vendor/symfony/polyfill-ctype/composer.json index d7c9abb65..995978c0a 100644 --- a/vendor/symfony/polyfill-ctype/composer.json +++ b/vendor/symfony/polyfill-ctype/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" }, @@ -28,7 +28,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", diff --git a/vendor/symfony/polyfill-iconv/Iconv.php b/vendor/symfony/polyfill-iconv/Iconv.php index 180b5bfff..c17a70dc2 100644 --- a/vendor/symfony/polyfill-iconv/Iconv.php +++ b/vendor/symfony/polyfill-iconv/Iconv.php @@ -36,14 +36,14 @@ namespace Symfony\Polyfill\Iconv; */ final class Iconv { - const ERROR_ILLEGAL_CHARACTER = 'iconv(): Detected an illegal character in input string'; - const ERROR_WRONG_CHARSET = 'iconv(): Wrong charset, conversion from `%s\' to `%s\' is not allowed'; + public const ERROR_ILLEGAL_CHARACTER = 'iconv(): Detected an illegal character in input string'; + public const ERROR_WRONG_CHARSET = 'iconv(): Wrong charset, conversion from `%s\' to `%s\' is not allowed'; public static $inputEncoding = 'utf-8'; public static $outputEncoding = 'utf-8'; public static $internalEncoding = 'utf-8'; - private static $alias = array( + private static $alias = [ 'utf8' => 'utf-8', 'ascii' => 'us-ascii', 'tis-620' => 'iso-8859-11', @@ -116,13 +116,13 @@ final class Iconv 'iso885914' => 'iso-8859-14', 'iso885915' => 'iso-8859-15', 'iso885916' => 'iso-8859-16', - ); - private static $translitMap = array(); - private static $convertMap = array(); + ]; + private static $translitMap = []; + private static $convertMap = []; private static $errorHandler; private static $lastError; - private static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4); + private static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; private static $isValidUtf8; public static function iconv($inCharset, $outCharset, $str) @@ -238,7 +238,7 @@ final class Iconv } $str = explode("\n\n", $str, 2); - $headers = array(); + $headers = []; $str = preg_split('/\n(?![ \t])/', $str[0]); foreach ($str as $str) { @@ -251,7 +251,7 @@ final class Iconv if (2 === \count($str)) { if (isset($headers[$str[0]])) { if (!\is_array($headers[$str[0]])) { - $headers[$str[0]] = array($headers[$str[0]]); + $headers[$str[0]] = [$headers[$str[0]]]; } $headers[$str[0]][] = ltrim($str[1]); } else { @@ -268,7 +268,7 @@ final class Iconv if (null === $charset) { $charset = self::$internalEncoding; } - if (ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) { + if (\ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) { $charset .= '//IGNORE'; } @@ -277,7 +277,7 @@ final class Iconv } $str = preg_split('/\n(?![ \t])/', rtrim($str), 2); $str = preg_replace('/[ \t]*\n[ \t]+/', ' ', rtrim($str[0])); - $str = preg_split('/=\?([^?]+)\?([bqBQ])\?(.*?)\?=/', $str, -1, PREG_SPLIT_DELIM_CAPTURE); + $str = preg_split('/=\?([^?]+)\?([bqBQ])\?(.*?)\?=/', $str, -1, \PREG_SPLIT_DELIM_CAPTURE); $result = self::iconv('utf-8', $charset, $str[0]); if (false === $result) { @@ -289,7 +289,7 @@ final class Iconv while ($i < $len) { $c = strtolower($str[$i]); - if ((ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) + if ((\ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) && 'utf-8' !== $c && !isset(self::$alias[$c]) && !self::loadMap('from.', $c, $d)) { @@ -312,7 +312,7 @@ final class Iconv if ('' !== trim($d)) { $result .= $d; } - } elseif (ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) { + } elseif (\ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) { $result .= "=?{$str[$i]}?{$str[$i + 1]}?{$str[$i + 2]}?={$str[$i + 3]}"; } else { $result = false; @@ -333,11 +333,11 @@ final class Iconv case 'internal_encoding': return self::$internalEncoding; } - return array( + return [ 'input_encoding' => self::$inputEncoding, 'output_encoding' => self::$outputEncoding, 'internal_encoding' => self::$internalEncoding, - ); + ]; } public static function iconv_set_encoding($type, $charset) @@ -346,7 +346,6 @@ final class Iconv case 'input_encoding': self::$inputEncoding = $charset; break; case 'output_encoding': self::$outputEncoding = $charset; break; case 'internal_encoding': self::$internalEncoding = $charset; break; - default: return false; } @@ -356,16 +355,16 @@ final class Iconv public static function iconv_mime_encode($fieldName, $fieldValue, $pref = null) { if (!\is_array($pref)) { - $pref = array(); + $pref = []; } - $pref += array( + $pref += [ 'scheme' => 'B', 'input-charset' => self::$internalEncoding, 'output-charset' => self::$internalEncoding, 'line-length' => 76, 'line-break-chars' => "\r\n", - ); + ]; if (preg_match('/[\x80-\xFF]/', $fieldName)) { $fieldName = ''; @@ -381,7 +380,7 @@ final class Iconv preg_match_all('/./us', $fieldValue, $chars); - $chars = isset($chars[0]) ? $chars[0] : array(); + $chars = $chars[0] ?? []; $lineBreak = (int) $pref['line-length']; $lineStart = "=?{$pref['output-charset']}?{$scheme}?"; @@ -389,7 +388,7 @@ final class Iconv $lineOffset = \strlen($lineStart) + 3; $lineData = ''; - $fieldValue = array(); + $fieldValue = []; $Q = 'Q' === $scheme; @@ -401,7 +400,7 @@ final class Iconv $o = $Q ? $c = preg_replace_callback( '/[=_\?\x00-\x1F\x80-\xFF]/', - array(__CLASS__, 'qpByteCallback'), + [__CLASS__, 'qpByteCallback'], $c ) : base64_encode($lineData.$c); @@ -472,7 +471,7 @@ final class Iconv while ($i < $len) { $u = $s[$i] & "\xF0"; - $i += isset($ulenMask[$u]) ? $ulenMask[$u] : 1; + $i += $ulenMask[$u] ?? 1; ++$j; } @@ -611,7 +610,7 @@ final class Iconv $u[$j++] = $str[$i++]; } else { $ulen = $str[$i] & "\xF0"; - $ulen = isset($ulenMask[$ulen]) ? $ulenMask[$ulen] : 1; + $ulen = $ulenMask[$ulen] ?? 1; $uchr = substr($str, $i, $ulen); if (1 === $ulen || !($valid || preg_match('/^.$/us', $uchr))) { @@ -623,10 +622,10 @@ final class Iconv trigger_error(self::ERROR_ILLEGAL_CHARACTER); return false; - } else { - $i += $ulen; } + $i += $ulen; + $u[$j++] = $uchr[0]; isset($uchr[1]) && 0 !== ($u[$j++] = $uchr[1]) @@ -673,15 +672,15 @@ final class Iconv $uchr = $str[$i++]; } else { $ulen = $str[$i] & "\xF0"; - $ulen = isset($ulenMask[$ulen]) ? $ulenMask[$ulen] : 1; + $ulen = $ulenMask[$ulen] ?? 1; $uchr = substr($str, $i, $ulen); if ($ignore && (1 === $ulen || !($valid || preg_match('/^.$/us', $uchr)))) { ++$i; continue; - } else { - $i += $ulen; } + + $i += $ulen; } if (isset($map[$uchr])) { @@ -723,7 +722,7 @@ final class Iconv private static function pregOffset($offset) { - $rx = array(); + $rx = []; $offset = (int) $offset; while ($offset > 65535) { diff --git a/vendor/symfony/polyfill-iconv/bootstrap.php b/vendor/symfony/polyfill-iconv/bootstrap.php index 6eb76fc5a..91fdba0dc 100644 --- a/vendor/symfony/polyfill-iconv/bootstrap.php +++ b/vendor/symfony/polyfill-iconv/bootstrap.php @@ -15,6 +15,10 @@ if (extension_loaded('iconv')) { return; } +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + if (!defined('ICONV_IMPL')) { define('ICONV_IMPL', 'Symfony'); } @@ -38,7 +42,7 @@ if (!function_exists('iconv_set_encoding')) { function iconv_set_encoding($type, $encoding) { return p\Iconv::iconv_set_encoding($type, $encoding); } } if (!function_exists('iconv_mime_encode')) { - function iconv_mime_encode($field_name, $field_value, $options = null) { return p\Iconv::iconv_mime_encode($field_name, $field_value, $options); } + function iconv_mime_encode($field_name, $field_value, $options = []) { return p\Iconv::iconv_mime_encode($field_name, $field_value, $options); } } if (!function_exists('iconv_mime_decode_headers')) { function iconv_mime_decode_headers($headers, $mode = 0, $encoding = null) { return p\Iconv::iconv_mime_decode_headers($headers, $mode, $encoding); } diff --git a/vendor/symfony/polyfill-iconv/bootstrap80.php b/vendor/symfony/polyfill-iconv/bootstrap80.php index 2dd8bf762..c46eb487b 100644 --- a/vendor/symfony/polyfill-iconv/bootstrap80.php +++ b/vendor/symfony/polyfill-iconv/bootstrap80.php @@ -25,33 +25,33 @@ if (!defined('ICONV_MIME_DECODE_CONTINUE_ON_ERROR')) { } if (!function_exists('iconv')) { - function iconv(string $from_encoding, string $to_encoding, string $string): string|false { return p\Iconv::iconv($from_encoding, $to_encoding, $string); } + function iconv(?string $from_encoding, ?string $to_encoding, ?string $string): string|false { return p\Iconv::iconv((string) $from_encoding, (string) $to_encoding, (string) $string); } } if (!function_exists('iconv_get_encoding')) { - function iconv_get_encoding(string $type = 'all'): array|string|false { return p\Iconv::iconv_get_encoding($type); } + function iconv_get_encoding(?string $type = 'all'): array|string|false { return p\Iconv::iconv_get_encoding((string) $type); } } if (!function_exists('iconv_set_encoding')) { - function iconv_set_encoding(string $type, string $encoding): bool { return p\Iconv::iconv_set_encoding($type, $encoding); } + function iconv_set_encoding(?string $type, ?string $encoding): bool { return p\Iconv::iconv_set_encoding((string) $type, (string) $encoding); } } if (!function_exists('iconv_mime_encode')) { - function iconv_mime_encode(string $field_name, string $field_value, array $options = []): string|false { return p\Iconv::iconv_mime_encode($field_name, $field_value, $options); } + function iconv_mime_encode(?string $field_name, ?string $field_value, ?array $options = []): string|false { return p\Iconv::iconv_mime_encode((string) $field_name, (string) $field_value, (array) $options); } } if (!function_exists('iconv_mime_decode_headers')) { - function iconv_mime_decode_headers(string $headers, int $mode = 0, string $encoding = null): array|false { return p\Iconv::iconv_mime_decode_headers($headers, $mode, $encoding); } + function iconv_mime_decode_headers(?string $headers, ?int $mode = 0, ?string $encoding = null): array|false { return p\Iconv::iconv_mime_decode_headers((string) $headers, (int) $mode, $encoding); } } if (extension_loaded('mbstring')) { if (!function_exists('iconv_strlen')) { - function iconv_strlen(string $string, string $encoding = null): int|false { null === $encoding && $encoding = p\Iconv::$internalEncoding; return mb_strlen($string, $encoding); } + function iconv_strlen(?string $string, ?string $encoding = null): int|false { null === $encoding && $encoding = p\Iconv::$internalEncoding; return mb_strlen((string) $string, $encoding); } } if (!function_exists('iconv_strpos')) { - function iconv_strpos(string $haystack, string $needle, int $offset = 0, string $encoding = null): int|false { null === $encoding && $encoding = p\Iconv::$internalEncoding; return mb_strpos($haystack, $needle, $offset, $encoding); } + function iconv_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { null === $encoding && $encoding = p\Iconv::$internalEncoding; return mb_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } } if (!function_exists('iconv_strrpos')) { - function iconv_strrpos(string $haystack, string $needle, string $encoding = null): int|false { null === $encoding && $encoding = p\Iconv::$internalEncoding; return mb_strrpos($haystack, $needle, 0, $encoding); } + function iconv_strrpos(?string $haystack, ?string $needle, ?string $encoding = null): int|false { null === $encoding && $encoding = p\Iconv::$internalEncoding; return mb_strrpos((string) $haystack, (string) $needle, 0, $encoding); } } if (!function_exists('iconv_substr')) { - function iconv_substr(string $string, int $offset, int $length = null, string $encoding = null): string|false { null === $encoding && $encoding = p\Iconv::$internalEncoding; return mb_substr($string, $offset, $length, $encoding); } + function iconv_substr(?string $string, ?int $offset, ?int $length = null, ?string $encoding = null): string|false { null === $encoding && $encoding = p\Iconv::$internalEncoding; return mb_substr((string) $string, (int) $offset, (int) $length, $encoding); } } if (!function_exists('iconv_mime_decode')) { function iconv_mime_decode($string, $mode = 0, $encoding = null) { null === $encoding && $encoding = p\Iconv::$internalEncoding; return mb_decode_mimeheader($string, $mode, $encoding); } @@ -59,22 +59,22 @@ if (extension_loaded('mbstring')) { } else { if (!function_exists('iconv_strlen')) { if (extension_loaded('xml')) { - function iconv_strlen(string $string, string $encoding = null): int|false { return p\Iconv::strlen1($string, $encoding); } + function iconv_strlen(?string $string, ?string $encoding = null): int|false { return p\Iconv::strlen1((string) $string, $encoding); } } else { - function iconv_strlen(string $string, string $encoding = null): int|false { return p\Iconv::strlen2($string, $encoding); } + function iconv_strlen(?string $string, ?string $encoding = null): int|false { return p\Iconv::strlen2((string) $string, $encoding); } } } if (!function_exists('iconv_strpos')) { - function iconv_strpos(string $haystack, string $needle, int $offset = 0, string $encoding = null): int|false { return p\Iconv::iconv_strpos($haystack, $needle, $offset, $encoding); } + function iconv_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Iconv::iconv_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } } if (!function_exists('iconv_strrpos')) { - function iconv_strrpos(string $haystack, string $needle, string $encoding = null): int|false { return p\Iconv::iconv_strrpos($haystack, $needle, $encoding); } + function iconv_strrpos(?string $haystack, ?string $needle, ?string $encoding = null): int|false { return p\Iconv::iconv_strrpos((string) $haystack, (string) $needle, $encoding); } } if (!function_exists('iconv_substr')) { - function iconv_substr(string $string, int $offset, int $length = null, string $encoding = null): string|false { return p\Iconv::iconv_substr($string, $offset, $length, $encoding); } + function iconv_substr(?string $string, ?int $offset, ?int $length = null, ?string $encoding = null): string|false { return p\Iconv::iconv_substr((string) $string, (string) $offset, (int) $length, $encoding); } } if (!function_exists('iconv_mime_decode')) { - function iconv_mime_decode(string $string, int $mode = 0, string $encoding = null): string|false { return p\Iconv::iconv_mime_decode($string, $mode, $encoding); } + function iconv_mime_decode(?string $string, ?int $mode = 0, ?string $encoding = null): string|false { return p\Iconv::iconv_mime_decode((string) $string, (int) $mode, $encoding); } } } diff --git a/vendor/symfony/polyfill-iconv/composer.json b/vendor/symfony/polyfill-iconv/composer.json index 727f74281..4669f3f1b 100644 --- a/vendor/symfony/polyfill-iconv/composer.json +++ b/vendor/symfony/polyfill-iconv/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Iconv\\": "" }, @@ -28,7 +28,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", diff --git a/vendor/symfony/polyfill-intl-idn/Idn.php b/vendor/symfony/polyfill-intl-idn/Idn.php index bccea3ec5..fee3026df 100644 --- a/vendor/symfony/polyfill-intl-idn/Idn.php +++ b/vendor/symfony/polyfill-intl-idn/Idn.php @@ -23,45 +23,45 @@ use Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex; */ final class Idn { - const ERROR_EMPTY_LABEL = 1; - const ERROR_LABEL_TOO_LONG = 2; - const ERROR_DOMAIN_NAME_TOO_LONG = 4; - const ERROR_LEADING_HYPHEN = 8; - const ERROR_TRAILING_HYPHEN = 0x10; - const ERROR_HYPHEN_3_4 = 0x20; - const ERROR_LEADING_COMBINING_MARK = 0x40; - const ERROR_DISALLOWED = 0x80; - const ERROR_PUNYCODE = 0x100; - const ERROR_LABEL_HAS_DOT = 0x200; - const ERROR_INVALID_ACE_LABEL = 0x400; - const ERROR_BIDI = 0x800; - const ERROR_CONTEXTJ = 0x1000; - const ERROR_CONTEXTO_PUNCTUATION = 0x2000; - const ERROR_CONTEXTO_DIGITS = 0x4000; + public const ERROR_EMPTY_LABEL = 1; + public const ERROR_LABEL_TOO_LONG = 2; + public const ERROR_DOMAIN_NAME_TOO_LONG = 4; + public const ERROR_LEADING_HYPHEN = 8; + public const ERROR_TRAILING_HYPHEN = 0x10; + public const ERROR_HYPHEN_3_4 = 0x20; + public const ERROR_LEADING_COMBINING_MARK = 0x40; + public const ERROR_DISALLOWED = 0x80; + public const ERROR_PUNYCODE = 0x100; + public const ERROR_LABEL_HAS_DOT = 0x200; + public const ERROR_INVALID_ACE_LABEL = 0x400; + public const ERROR_BIDI = 0x800; + public const ERROR_CONTEXTJ = 0x1000; + public const ERROR_CONTEXTO_PUNCTUATION = 0x2000; + public const ERROR_CONTEXTO_DIGITS = 0x4000; - const INTL_IDNA_VARIANT_2003 = 0; - const INTL_IDNA_VARIANT_UTS46 = 1; + public const INTL_IDNA_VARIANT_2003 = 0; + public const INTL_IDNA_VARIANT_UTS46 = 1; - const IDNA_DEFAULT = 0; - const IDNA_ALLOW_UNASSIGNED = 1; - const IDNA_USE_STD3_RULES = 2; - const IDNA_CHECK_BIDI = 4; - const IDNA_CHECK_CONTEXTJ = 8; - const IDNA_NONTRANSITIONAL_TO_ASCII = 16; - const IDNA_NONTRANSITIONAL_TO_UNICODE = 32; + public const IDNA_DEFAULT = 0; + public const IDNA_ALLOW_UNASSIGNED = 1; + public const IDNA_USE_STD3_RULES = 2; + public const IDNA_CHECK_BIDI = 4; + public const IDNA_CHECK_CONTEXTJ = 8; + public const IDNA_NONTRANSITIONAL_TO_ASCII = 16; + public const IDNA_NONTRANSITIONAL_TO_UNICODE = 32; - const MAX_DOMAIN_SIZE = 253; - const MAX_LABEL_SIZE = 63; + public const MAX_DOMAIN_SIZE = 253; + public const MAX_LABEL_SIZE = 63; - const BASE = 36; - const TMIN = 1; - const TMAX = 26; - const SKEW = 38; - const DAMP = 700; - const INITIAL_BIAS = 72; - const INITIAL_N = 128; - const DELIMITER = '-'; - const MAX_INT = 2147483647; + public const BASE = 36; + public const TMIN = 1; + public const TMAX = 26; + public const SKEW = 38; + public const DAMP = 700; + public const INITIAL_BIAS = 72; + public const INITIAL_N = 128; + public const DELIMITER = '-'; + public const MAX_INT = 2147483647; /** * Contains the numeric value of a basic code point (for use in representing integers) in the @@ -69,7 +69,7 @@ final class Idn * * @var array */ - private static $basicToDigit = array( + private static $basicToDigit = [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -93,7 +93,7 @@ final class Idn -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - ); + ]; /** * @var array @@ -145,20 +145,20 @@ final class Idn * * @return string|false */ - public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) + public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = []) { 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); + @trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); } - $options = array( + $options = [ 'CheckHyphens' => true, 'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & self::IDNA_CHECK_BIDI), 'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & self::IDNA_CHECK_CONTEXTJ), 'UseSTD3ASCIIRules' => 0 !== ($options & self::IDNA_USE_STD3_RULES), 'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & self::IDNA_NONTRANSITIONAL_TO_ASCII), 'VerifyDnsLength' => true, - ); + ]; $info = new Info(); $labels = self::process((string) $domainName, $options, $info); @@ -179,11 +179,11 @@ final class Idn self::validateDomainAndLabelLength($labels, $info); } - $idna_info = array( + $idna_info = [ 'result' => implode('.', $labels), 'isTransitionalDifferent' => $info->transitionalDifferent, 'errors' => $info->errors, - ); + ]; return 0 === $info->errors ? $idna_info['result'] : false; } @@ -198,25 +198,25 @@ final class Idn * * @return string|false */ - public static function idn_to_utf8($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) + public static function idn_to_utf8($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = []) { 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); + @trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); } $info = new Info(); - $labels = self::process((string) $domainName, array( + $labels = self::process((string) $domainName, [ 'CheckHyphens' => true, 'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & self::IDNA_CHECK_BIDI), 'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & self::IDNA_CHECK_CONTEXTJ), 'UseSTD3ASCIIRules' => 0 !== ($options & self::IDNA_USE_STD3_RULES), 'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & self::IDNA_NONTRANSITIONAL_TO_UNICODE), - ), $info); - $idna_info = array( + ], $info); + $idna_info = [ 'result' => implode('.', $labels), 'isTransitionalDifferent' => $info->transitionalDifferent, 'errors' => $info->errors, - ); + ]; return 0 === $info->errors ? $idna_info['result'] : false; } @@ -251,7 +251,7 @@ final class Idn // If RegExpMatch((Joining_Type:{L,D})(Joining_Type:T)*\u200C(Joining_Type:T)*(Joining_Type:{R,D})) Then // True; // Generated RegExp = ([Joining_Type:{L,D}][Joining_Type:T]*\u200C[Joining_Type:T]*)[Joining_Type:{R,D}] - if (0x200C === $codePoint && 1 === preg_match(Regex::ZWNJ, $label, $matches, PREG_OFFSET_CAPTURE, $offset)) { + if (0x200C === $codePoint && 1 === preg_match(Regex::ZWNJ, $label, $matches, \PREG_OFFSET_CAPTURE, $offset)) { $offset += \strlen($matches[1][0]); continue; @@ -328,7 +328,7 @@ final class Idn if ($checkForEmptyLabels && '' === $domain) { $info->errors |= self::ERROR_EMPTY_LABEL; - return array($domain); + return [$domain]; } // Step 1. Map each code point in the domain name string @@ -578,7 +578,7 @@ final class Idn $lastDelimIndex = strrpos($input, self::DELIMITER); $b = false === $lastDelimIndex ? 0 : $lastDelimIndex; $inputLength = \strlen($input); - $output = array(); + $output = []; $bytes = array_map('ord', str_split($input)); for ($j = 0; $j < $b; ++$j) { @@ -644,7 +644,7 @@ final class Idn $n += intdiv($i, $outPlusOne); $i %= $outPlusOne; - array_splice($output, $i++, 0, array(mb_chr($n, 'utf-8'))); + array_splice($output, $i++, 0, [mb_chr($n, 'utf-8')]); } return implode('', $output); @@ -703,7 +703,9 @@ final class Idn foreach ($iter as $codePoint) { if ($codePoint < $n && 0 === ++$delta) { throw new Exception('Integer overflow'); - } elseif ($codePoint === $n) { + } + + if ($codePoint === $n) { $q = $delta; for ($k = self::BASE; /* no condition */; $k += self::BASE) { @@ -793,7 +795,7 @@ final class Idn $lowerBoundary = 0x80; $upperBoundary = 0xBF; $codePoint = 0; - $codePoints = array(); + $codePoints = []; $length = \strlen($input); for ($i = 0; $i < $length; ++$i) { @@ -887,19 +889,19 @@ final class Idn } if (isset(self::$mapped[$codePoint])) { - return array('status' => 'mapped', 'mapping' => self::$mapped[$codePoint]); + return ['status' => 'mapped', 'mapping' => self::$mapped[$codePoint]]; } if (isset(self::$ignored[$codePoint])) { - return array('status' => 'ignored'); + return ['status' => 'ignored']; } if (isset(self::$deviation[$codePoint])) { - return array('status' => 'deviation', 'mapping' => self::$deviation[$codePoint]); + return ['status' => 'deviation', 'mapping' => self::$deviation[$codePoint]]; } if (isset(self::$disallowed[$codePoint]) || DisallowedRanges::inRange($codePoint)) { - return array('status' => 'disallowed'); + return ['status' => 'disallowed']; } $isDisallowedMapped = isset(self::$disallowed_STD3_mapped[$codePoint]); @@ -912,12 +914,12 @@ final class Idn } if ($isDisallowedMapped) { - return array('status' => $status, 'mapping' => self::$disallowed_STD3_mapped[$codePoint]); + return ['status' => $status, 'mapping' => self::$disallowed_STD3_mapped[$codePoint]]; } - return array('status' => $status); + return ['status' => $status]; } - return array('status' => 'valid'); + return ['status' => 'valid']; } } diff --git a/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php b/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php index 5c1c51dde..c4b9778e5 100644 --- a/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php +++ b/vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php @@ -7,18 +7,18 @@ namespace Symfony\Polyfill\Intl\Idn\Resources\unidata; */ final class Regex { - const COMBINING_MARK = '/^[\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{0903}\x{093A}\x{093B}\x{093C}\x{093E}-\x{0940}\x{0941}-\x{0948}\x{0949}-\x{094C}\x{094D}\x{094E}-\x{094F}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{0982}-\x{0983}\x{09BC}\x{09BE}-\x{09C0}\x{09C1}-\x{09C4}\x{09C7}-\x{09C8}\x{09CB}-\x{09CC}\x{09CD}\x{09D7}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A03}\x{0A3C}\x{0A3E}-\x{0A40}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0A83}\x{0ABC}\x{0ABE}-\x{0AC0}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0AC9}\x{0ACB}-\x{0ACC}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B02}-\x{0B03}\x{0B3C}\x{0B3E}\x{0B3F}\x{0B40}\x{0B41}-\x{0B44}\x{0B47}-\x{0B48}\x{0B4B}-\x{0B4C}\x{0B4D}\x{0B55}-\x{0B56}\x{0B57}\x{0B62}-\x{0B63}\x{0B82}\x{0BBE}-\x{0BBF}\x{0BC0}\x{0BC1}-\x{0BC2}\x{0BC6}-\x{0BC8}\x{0BCA}-\x{0BCC}\x{0BCD}\x{0BD7}\x{0C00}\x{0C01}-\x{0C03}\x{0C04}\x{0C3E}-\x{0C40}\x{0C41}-\x{0C44}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0C82}-\x{0C83}\x{0CBC}\x{0CBE}\x{0CBF}\x{0CC0}-\x{0CC4}\x{0CC6}\x{0CC7}-\x{0CC8}\x{0CCA}-\x{0CCB}\x{0CCC}-\x{0CCD}\x{0CD5}-\x{0CD6}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D02}-\x{0D03}\x{0D3B}-\x{0D3C}\x{0D3E}-\x{0D40}\x{0D41}-\x{0D44}\x{0D46}-\x{0D48}\x{0D4A}-\x{0D4C}\x{0D4D}\x{0D57}\x{0D62}-\x{0D63}\x{0D81}\x{0D82}-\x{0D83}\x{0DCA}\x{0DCF}-\x{0DD1}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0DD8}-\x{0DDF}\x{0DF2}-\x{0DF3}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3E}-\x{0F3F}\x{0F71}-\x{0F7E}\x{0F7F}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102B}-\x{102C}\x{102D}-\x{1030}\x{1031}\x{1032}-\x{1037}\x{1038}\x{1039}-\x{103A}\x{103B}-\x{103C}\x{103D}-\x{103E}\x{1056}-\x{1057}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1062}-\x{1064}\x{1067}-\x{106D}\x{1071}-\x{1074}\x{1082}\x{1083}-\x{1084}\x{1085}-\x{1086}\x{1087}-\x{108C}\x{108D}\x{108F}\x{109A}-\x{109C}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B6}\x{17B7}-\x{17BD}\x{17BE}-\x{17C5}\x{17C6}\x{17C7}-\x{17C8}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1923}-\x{1926}\x{1927}-\x{1928}\x{1929}-\x{192B}\x{1930}-\x{1931}\x{1932}\x{1933}-\x{1938}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A19}-\x{1A1A}\x{1A1B}\x{1A55}\x{1A56}\x{1A57}\x{1A58}-\x{1A5E}\x{1A60}\x{1A61}\x{1A62}\x{1A63}-\x{1A64}\x{1A65}-\x{1A6C}\x{1A6D}-\x{1A72}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B04}\x{1B34}\x{1B35}\x{1B36}-\x{1B3A}\x{1B3B}\x{1B3C}\x{1B3D}-\x{1B41}\x{1B42}\x{1B43}-\x{1B44}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1B82}\x{1BA1}\x{1BA2}-\x{1BA5}\x{1BA6}-\x{1BA7}\x{1BA8}-\x{1BA9}\x{1BAA}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE7}\x{1BE8}-\x{1BE9}\x{1BEA}-\x{1BEC}\x{1BED}\x{1BEE}\x{1BEF}-\x{1BF1}\x{1BF2}-\x{1BF3}\x{1C24}-\x{1C2B}\x{1C2C}-\x{1C33}\x{1C34}-\x{1C35}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE1}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF7}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{302E}-\x{302F}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A823}-\x{A824}\x{A825}-\x{A826}\x{A827}\x{A82C}\x{A880}-\x{A881}\x{A8B4}-\x{A8C3}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A952}-\x{A953}\x{A980}-\x{A982}\x{A983}\x{A9B3}\x{A9B4}-\x{A9B5}\x{A9B6}-\x{A9B9}\x{A9BA}-\x{A9BB}\x{A9BC}-\x{A9BD}\x{A9BE}-\x{A9C0}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA2F}-\x{AA30}\x{AA31}-\x{AA32}\x{AA33}-\x{AA34}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA4D}\x{AA7B}\x{AA7C}\x{AA7D}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEB}\x{AAEC}-\x{AAED}\x{AAEE}-\x{AAEF}\x{AAF5}\x{AAF6}\x{ABE3}-\x{ABE4}\x{ABE5}\x{ABE6}-\x{ABE7}\x{ABE8}\x{ABE9}-\x{ABEA}\x{ABEC}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11000}\x{11001}\x{11002}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{11082}\x{110B0}-\x{110B2}\x{110B3}-\x{110B6}\x{110B7}-\x{110B8}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112C}\x{1112D}-\x{11134}\x{11145}-\x{11146}\x{11173}\x{11180}-\x{11181}\x{11182}\x{111B3}-\x{111B5}\x{111B6}-\x{111BE}\x{111BF}-\x{111C0}\x{111C9}-\x{111CC}\x{111CE}\x{111CF}\x{1122C}-\x{1122E}\x{1122F}-\x{11231}\x{11232}-\x{11233}\x{11234}\x{11235}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E0}-\x{112E2}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{11302}-\x{11303}\x{1133B}-\x{1133C}\x{1133E}-\x{1133F}\x{11340}\x{11341}-\x{11344}\x{11347}-\x{11348}\x{1134B}-\x{1134D}\x{11357}\x{11362}-\x{11363}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11435}-\x{11437}\x{11438}-\x{1143F}\x{11440}-\x{11441}\x{11442}-\x{11444}\x{11445}\x{11446}\x{1145E}\x{114B0}-\x{114B2}\x{114B3}-\x{114B8}\x{114B9}\x{114BA}\x{114BB}-\x{114BE}\x{114BF}-\x{114C0}\x{114C1}\x{114C2}-\x{114C3}\x{115AF}-\x{115B1}\x{115B2}-\x{115B5}\x{115B8}-\x{115BB}\x{115BC}-\x{115BD}\x{115BE}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11630}-\x{11632}\x{11633}-\x{1163A}\x{1163B}-\x{1163C}\x{1163D}\x{1163E}\x{1163F}-\x{11640}\x{116AB}\x{116AC}\x{116AD}\x{116AE}-\x{116AF}\x{116B0}-\x{116B5}\x{116B6}\x{116B7}\x{1171D}-\x{1171F}\x{11720}-\x{11721}\x{11722}-\x{11725}\x{11726}\x{11727}-\x{1172B}\x{1182C}-\x{1182E}\x{1182F}-\x{11837}\x{11838}\x{11839}-\x{1183A}\x{11930}-\x{11935}\x{11937}-\x{11938}\x{1193B}-\x{1193C}\x{1193D}\x{1193E}\x{11940}\x{11942}\x{11943}\x{119D1}-\x{119D3}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119DC}-\x{119DF}\x{119E0}\x{119E4}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A39}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A57}-\x{11A58}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A97}\x{11A98}-\x{11A99}\x{11C2F}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3E}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CA9}\x{11CAA}-\x{11CB0}\x{11CB1}\x{11CB2}-\x{11CB3}\x{11CB4}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D8A}-\x{11D8E}\x{11D90}-\x{11D91}\x{11D93}-\x{11D94}\x{11D95}\x{11D96}\x{11D97}\x{11EF3}-\x{11EF4}\x{11EF5}-\x{11EF6}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F51}-\x{16F87}\x{16F8F}-\x{16F92}\x{16FE4}\x{16FF0}-\x{16FF1}\x{1BC9D}-\x{1BC9E}\x{1D165}-\x{1D166}\x{1D167}-\x{1D169}\x{1D16D}-\x{1D172}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]/u'; + public const COMBINING_MARK = '/^[\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{0903}\x{093A}\x{093B}\x{093C}\x{093E}-\x{0940}\x{0941}-\x{0948}\x{0949}-\x{094C}\x{094D}\x{094E}-\x{094F}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{0982}-\x{0983}\x{09BC}\x{09BE}-\x{09C0}\x{09C1}-\x{09C4}\x{09C7}-\x{09C8}\x{09CB}-\x{09CC}\x{09CD}\x{09D7}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A03}\x{0A3C}\x{0A3E}-\x{0A40}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0A83}\x{0ABC}\x{0ABE}-\x{0AC0}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0AC9}\x{0ACB}-\x{0ACC}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B02}-\x{0B03}\x{0B3C}\x{0B3E}\x{0B3F}\x{0B40}\x{0B41}-\x{0B44}\x{0B47}-\x{0B48}\x{0B4B}-\x{0B4C}\x{0B4D}\x{0B55}-\x{0B56}\x{0B57}\x{0B62}-\x{0B63}\x{0B82}\x{0BBE}-\x{0BBF}\x{0BC0}\x{0BC1}-\x{0BC2}\x{0BC6}-\x{0BC8}\x{0BCA}-\x{0BCC}\x{0BCD}\x{0BD7}\x{0C00}\x{0C01}-\x{0C03}\x{0C04}\x{0C3E}-\x{0C40}\x{0C41}-\x{0C44}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0C82}-\x{0C83}\x{0CBC}\x{0CBE}\x{0CBF}\x{0CC0}-\x{0CC4}\x{0CC6}\x{0CC7}-\x{0CC8}\x{0CCA}-\x{0CCB}\x{0CCC}-\x{0CCD}\x{0CD5}-\x{0CD6}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D02}-\x{0D03}\x{0D3B}-\x{0D3C}\x{0D3E}-\x{0D40}\x{0D41}-\x{0D44}\x{0D46}-\x{0D48}\x{0D4A}-\x{0D4C}\x{0D4D}\x{0D57}\x{0D62}-\x{0D63}\x{0D81}\x{0D82}-\x{0D83}\x{0DCA}\x{0DCF}-\x{0DD1}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0DD8}-\x{0DDF}\x{0DF2}-\x{0DF3}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3E}-\x{0F3F}\x{0F71}-\x{0F7E}\x{0F7F}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102B}-\x{102C}\x{102D}-\x{1030}\x{1031}\x{1032}-\x{1037}\x{1038}\x{1039}-\x{103A}\x{103B}-\x{103C}\x{103D}-\x{103E}\x{1056}-\x{1057}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1062}-\x{1064}\x{1067}-\x{106D}\x{1071}-\x{1074}\x{1082}\x{1083}-\x{1084}\x{1085}-\x{1086}\x{1087}-\x{108C}\x{108D}\x{108F}\x{109A}-\x{109C}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B6}\x{17B7}-\x{17BD}\x{17BE}-\x{17C5}\x{17C6}\x{17C7}-\x{17C8}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1923}-\x{1926}\x{1927}-\x{1928}\x{1929}-\x{192B}\x{1930}-\x{1931}\x{1932}\x{1933}-\x{1938}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A19}-\x{1A1A}\x{1A1B}\x{1A55}\x{1A56}\x{1A57}\x{1A58}-\x{1A5E}\x{1A60}\x{1A61}\x{1A62}\x{1A63}-\x{1A64}\x{1A65}-\x{1A6C}\x{1A6D}-\x{1A72}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B04}\x{1B34}\x{1B35}\x{1B36}-\x{1B3A}\x{1B3B}\x{1B3C}\x{1B3D}-\x{1B41}\x{1B42}\x{1B43}-\x{1B44}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1B82}\x{1BA1}\x{1BA2}-\x{1BA5}\x{1BA6}-\x{1BA7}\x{1BA8}-\x{1BA9}\x{1BAA}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE7}\x{1BE8}-\x{1BE9}\x{1BEA}-\x{1BEC}\x{1BED}\x{1BEE}\x{1BEF}-\x{1BF1}\x{1BF2}-\x{1BF3}\x{1C24}-\x{1C2B}\x{1C2C}-\x{1C33}\x{1C34}-\x{1C35}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE1}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF7}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{302E}-\x{302F}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A823}-\x{A824}\x{A825}-\x{A826}\x{A827}\x{A82C}\x{A880}-\x{A881}\x{A8B4}-\x{A8C3}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A952}-\x{A953}\x{A980}-\x{A982}\x{A983}\x{A9B3}\x{A9B4}-\x{A9B5}\x{A9B6}-\x{A9B9}\x{A9BA}-\x{A9BB}\x{A9BC}-\x{A9BD}\x{A9BE}-\x{A9C0}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA2F}-\x{AA30}\x{AA31}-\x{AA32}\x{AA33}-\x{AA34}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA4D}\x{AA7B}\x{AA7C}\x{AA7D}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEB}\x{AAEC}-\x{AAED}\x{AAEE}-\x{AAEF}\x{AAF5}\x{AAF6}\x{ABE3}-\x{ABE4}\x{ABE5}\x{ABE6}-\x{ABE7}\x{ABE8}\x{ABE9}-\x{ABEA}\x{ABEC}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11000}\x{11001}\x{11002}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{11082}\x{110B0}-\x{110B2}\x{110B3}-\x{110B6}\x{110B7}-\x{110B8}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112C}\x{1112D}-\x{11134}\x{11145}-\x{11146}\x{11173}\x{11180}-\x{11181}\x{11182}\x{111B3}-\x{111B5}\x{111B6}-\x{111BE}\x{111BF}-\x{111C0}\x{111C9}-\x{111CC}\x{111CE}\x{111CF}\x{1122C}-\x{1122E}\x{1122F}-\x{11231}\x{11232}-\x{11233}\x{11234}\x{11235}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E0}-\x{112E2}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{11302}-\x{11303}\x{1133B}-\x{1133C}\x{1133E}-\x{1133F}\x{11340}\x{11341}-\x{11344}\x{11347}-\x{11348}\x{1134B}-\x{1134D}\x{11357}\x{11362}-\x{11363}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11435}-\x{11437}\x{11438}-\x{1143F}\x{11440}-\x{11441}\x{11442}-\x{11444}\x{11445}\x{11446}\x{1145E}\x{114B0}-\x{114B2}\x{114B3}-\x{114B8}\x{114B9}\x{114BA}\x{114BB}-\x{114BE}\x{114BF}-\x{114C0}\x{114C1}\x{114C2}-\x{114C3}\x{115AF}-\x{115B1}\x{115B2}-\x{115B5}\x{115B8}-\x{115BB}\x{115BC}-\x{115BD}\x{115BE}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11630}-\x{11632}\x{11633}-\x{1163A}\x{1163B}-\x{1163C}\x{1163D}\x{1163E}\x{1163F}-\x{11640}\x{116AB}\x{116AC}\x{116AD}\x{116AE}-\x{116AF}\x{116B0}-\x{116B5}\x{116B6}\x{116B7}\x{1171D}-\x{1171F}\x{11720}-\x{11721}\x{11722}-\x{11725}\x{11726}\x{11727}-\x{1172B}\x{1182C}-\x{1182E}\x{1182F}-\x{11837}\x{11838}\x{11839}-\x{1183A}\x{11930}-\x{11935}\x{11937}-\x{11938}\x{1193B}-\x{1193C}\x{1193D}\x{1193E}\x{11940}\x{11942}\x{11943}\x{119D1}-\x{119D3}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119DC}-\x{119DF}\x{119E0}\x{119E4}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A39}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A57}-\x{11A58}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A97}\x{11A98}-\x{11A99}\x{11C2F}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3E}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CA9}\x{11CAA}-\x{11CB0}\x{11CB1}\x{11CB2}-\x{11CB3}\x{11CB4}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D8A}-\x{11D8E}\x{11D90}-\x{11D91}\x{11D93}-\x{11D94}\x{11D95}\x{11D96}\x{11D97}\x{11EF3}-\x{11EF4}\x{11EF5}-\x{11EF6}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F51}-\x{16F87}\x{16F8F}-\x{16F92}\x{16FE4}\x{16FF0}-\x{16FF1}\x{1BC9D}-\x{1BC9E}\x{1D165}-\x{1D166}\x{1D167}-\x{1D169}\x{1D16D}-\x{1D172}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]/u'; - const RTL_LABEL = '/[\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{200F}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; + public const RTL_LABEL = '/[\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{200F}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; - const BIDI_STEP_1_LTR = '/^[^\x{0000}-\x{0008}\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{000E}-\x{001B}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{0030}-\x{0039}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0085}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B2}-\x{00B3}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00B9}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{1680}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{2000}-\x{200A}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{205F}\x{2060}-\x{2064}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}\x{206A}-\x{206F}\x{2070}\x{2074}-\x{2079}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{2080}-\x{2089}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{2488}-\x{249B}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3000}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF10}-\x{FF19}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{102E1}-\x{102FB}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1D7CE}-\x{1D7FF}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F100}-\x{1F10A}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FBF0}-\x{1FBF9}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}]/u'; - const BIDI_STEP_1_RTL = '/^[\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{200F}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; - const BIDI_STEP_2 = '/[^\x{0000}-\x{0008}\x{000E}-\x{001B}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{0030}-\x{0039}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B2}-\x{00B3}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00B9}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{2060}-\x{2064}\x{2065}\x{206A}-\x{206F}\x{2070}\x{2074}-\x{2079}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{2080}-\x{2089}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{2488}-\x{249B}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF10}-\x{FF19}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{102E1}-\x{102FB}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1D7CE}-\x{1D7FF}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F100}-\x{1F10A}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FBF0}-\x{1FBF9}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}]/u'; - const BIDI_STEP_3 = '/[\x{0030}-\x{0039}\x{00B2}-\x{00B3}\x{00B9}\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{200F}\x{2070}\x{2074}-\x{2079}\x{2080}-\x{2089}\x{2488}-\x{249B}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FF10}-\x{FF19}\x{102E1}-\x{102FB}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1D7CE}-\x{1D7FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F100}-\x{1F10A}\x{1FBF0}-\x{1FBF9}][\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1D167}-\x{1D169}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]*$/u'; - const BIDI_STEP_4_AN = '/[\x{0600}-\x{0605}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{06DD}\x{08E2}\x{10D30}-\x{10D39}\x{10E60}-\x{10E7E}]/u'; - const BIDI_STEP_4_EN = '/[\x{0030}-\x{0039}\x{00B2}-\x{00B3}\x{00B9}\x{06F0}-\x{06F9}\x{2070}\x{2074}-\x{2079}\x{2080}-\x{2089}\x{2488}-\x{249B}\x{FF10}-\x{FF19}\x{102E1}-\x{102FB}\x{1D7CE}-\x{1D7FF}\x{1F100}-\x{1F10A}\x{1FBF0}-\x{1FBF9}]/u'; - const BIDI_STEP_5 = '/[\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0085}\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{1680}\x{2000}-\x{200A}\x{200F}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{205F}\x{2066}\x{2067}\x{2068}\x{2069}\x{3000}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; - const BIDI_STEP_6 = '/[^\x{0000}-\x{0008}\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{000E}-\x{001B}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0085}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{1680}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{2000}-\x{200A}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{205F}\x{2060}-\x{2064}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}\x{206A}-\x{206F}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3000}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}][\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1D167}-\x{1D169}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]*$/u'; + public const BIDI_STEP_1_LTR = '/^[^\x{0000}-\x{0008}\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{000E}-\x{001B}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{0030}-\x{0039}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0085}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B2}-\x{00B3}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00B9}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{1680}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{2000}-\x{200A}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{205F}\x{2060}-\x{2064}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}\x{206A}-\x{206F}\x{2070}\x{2074}-\x{2079}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{2080}-\x{2089}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{2488}-\x{249B}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3000}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF10}-\x{FF19}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{102E1}-\x{102FB}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1D7CE}-\x{1D7FF}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F100}-\x{1F10A}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FBF0}-\x{1FBF9}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}]/u'; + public const BIDI_STEP_1_RTL = '/^[\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{200F}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; + public const BIDI_STEP_2 = '/[^\x{0000}-\x{0008}\x{000E}-\x{001B}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{0030}-\x{0039}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B2}-\x{00B3}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00B9}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{2060}-\x{2064}\x{2065}\x{206A}-\x{206F}\x{2070}\x{2074}-\x{2079}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{2080}-\x{2089}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{2488}-\x{249B}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF10}-\x{FF19}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{102E1}-\x{102FB}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1D7CE}-\x{1D7FF}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F100}-\x{1F10A}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FBF0}-\x{1FBF9}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}]/u'; + public const BIDI_STEP_3 = '/[\x{0030}-\x{0039}\x{00B2}-\x{00B3}\x{00B9}\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06F0}-\x{06F9}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{200F}\x{2070}\x{2074}-\x{2079}\x{2080}-\x{2089}\x{2488}-\x{249B}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FF10}-\x{FF19}\x{102E1}-\x{102FB}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1D7CE}-\x{1D7FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F100}-\x{1F10A}\x{1FBF0}-\x{1FBF9}][\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1D167}-\x{1D169}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]*$/u'; + public const BIDI_STEP_4_AN = '/[\x{0600}-\x{0605}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{06DD}\x{08E2}\x{10D30}-\x{10D39}\x{10E60}-\x{10E7E}]/u'; + public const BIDI_STEP_4_EN = '/[\x{0030}-\x{0039}\x{00B2}-\x{00B3}\x{00B9}\x{06F0}-\x{06F9}\x{2070}\x{2074}-\x{2079}\x{2080}-\x{2089}\x{2488}-\x{249B}\x{FF10}-\x{FF19}\x{102E1}-\x{102FB}\x{1D7CE}-\x{1D7FF}\x{1F100}-\x{1F10A}\x{1FBF0}-\x{1FBF9}]/u'; + public const BIDI_STEP_5 = '/[\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0085}\x{0590}\x{05BE}\x{05C0}\x{05C3}\x{05C6}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0608}\x{060B}\x{060D}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{0660}-\x{0669}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06DD}\x{06E5}-\x{06E6}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0712}-\x{072F}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07F4}-\x{07F5}\x{07FA}\x{07FB}-\x{07FC}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{081A}\x{0824}\x{0828}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08E2}\x{1680}\x{2000}-\x{200A}\x{200F}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{205F}\x{2066}\x{2067}\x{2068}\x{2069}\x{3000}\x{FB1D}\x{FB1F}-\x{FB28}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFE}-\x{FDFF}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A04}\x{10A07}-\x{10A0B}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A3B}-\x{10A3E}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}]/u'; + public const BIDI_STEP_6 = '/[^\x{0000}-\x{0008}\x{0009}\x{000A}\x{000B}\x{000C}\x{000D}\x{000E}-\x{001B}\x{001C}-\x{001E}\x{001F}\x{0020}\x{0021}-\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}-\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}-\x{002F}\x{003A}\x{003B}\x{003C}-\x{003E}\x{003F}-\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{007F}-\x{0084}\x{0085}\x{0086}-\x{009F}\x{00A0}\x{00A1}\x{00A2}-\x{00A5}\x{00A6}\x{00A7}\x{00A8}\x{00A9}\x{00AB}\x{00AC}\x{00AD}\x{00AE}\x{00AF}\x{00B0}\x{00B1}\x{00B4}\x{00B6}-\x{00B7}\x{00B8}\x{00BB}\x{00BC}-\x{00BE}\x{00BF}\x{00D7}\x{00F7}\x{02B9}-\x{02BA}\x{02C2}-\x{02C5}\x{02C6}-\x{02CF}\x{02D2}-\x{02DF}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037E}\x{0384}-\x{0385}\x{0387}\x{03F6}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{058A}\x{058D}-\x{058E}\x{058F}\x{0590}\x{0591}-\x{05BD}\x{05BE}\x{05BF}\x{05C0}\x{05C1}-\x{05C2}\x{05C3}\x{05C4}-\x{05C5}\x{05C6}\x{05C7}\x{05C8}-\x{05CF}\x{05D0}-\x{05EA}\x{05EB}-\x{05EE}\x{05EF}-\x{05F2}\x{05F3}-\x{05F4}\x{05F5}-\x{05FF}\x{0600}-\x{0605}\x{0606}-\x{0607}\x{0608}\x{0609}-\x{060A}\x{060B}\x{060C}\x{060D}\x{060E}-\x{060F}\x{0610}-\x{061A}\x{061B}\x{061C}\x{061D}\x{061E}-\x{061F}\x{0620}-\x{063F}\x{0640}\x{0641}-\x{064A}\x{064B}-\x{065F}\x{0660}-\x{0669}\x{066A}\x{066B}-\x{066C}\x{066D}\x{066E}-\x{066F}\x{0670}\x{0671}-\x{06D3}\x{06D4}\x{06D5}\x{06D6}-\x{06DC}\x{06DD}\x{06DE}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06E9}\x{06EA}-\x{06ED}\x{06EE}-\x{06EF}\x{06FA}-\x{06FC}\x{06FD}-\x{06FE}\x{06FF}\x{0700}-\x{070D}\x{070E}\x{070F}\x{0710}\x{0711}\x{0712}-\x{072F}\x{0730}-\x{074A}\x{074B}-\x{074C}\x{074D}-\x{07A5}\x{07A6}-\x{07B0}\x{07B1}\x{07B2}-\x{07BF}\x{07C0}-\x{07C9}\x{07CA}-\x{07EA}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07F6}\x{07F7}-\x{07F9}\x{07FA}\x{07FB}-\x{07FC}\x{07FD}\x{07FE}-\x{07FF}\x{0800}-\x{0815}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{082E}-\x{082F}\x{0830}-\x{083E}\x{083F}\x{0840}-\x{0858}\x{0859}-\x{085B}\x{085C}-\x{085D}\x{085E}\x{085F}\x{0860}-\x{086A}\x{086B}-\x{086F}\x{0870}-\x{089F}\x{08A0}-\x{08B4}\x{08B5}\x{08B6}-\x{08C7}\x{08C8}-\x{08D2}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09F2}-\x{09F3}\x{09FB}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AF1}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0BF3}-\x{0BF8}\x{0BF9}\x{0BFA}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C78}-\x{0C7E}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E3F}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F3A}\x{0F3B}\x{0F3C}\x{0F3D}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1390}-\x{1399}\x{1400}\x{1680}\x{169B}\x{169C}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DB}\x{17DD}\x{17F0}-\x{17F9}\x{1800}-\x{1805}\x{1806}\x{1807}-\x{180A}\x{180B}-\x{180D}\x{180E}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1940}\x{1944}-\x{1945}\x{19DE}-\x{19FF}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{2000}-\x{200A}\x{200B}-\x{200D}\x{200F}\x{2010}-\x{2015}\x{2016}-\x{2017}\x{2018}\x{2019}\x{201A}\x{201B}-\x{201C}\x{201D}\x{201E}\x{201F}\x{2020}-\x{2027}\x{2028}\x{2029}\x{202A}\x{202B}\x{202C}\x{202D}\x{202E}\x{202F}\x{2030}-\x{2034}\x{2035}-\x{2038}\x{2039}\x{203A}\x{203B}-\x{203E}\x{203F}-\x{2040}\x{2041}-\x{2043}\x{2044}\x{2045}\x{2046}\x{2047}-\x{2051}\x{2052}\x{2053}\x{2054}\x{2055}-\x{205E}\x{205F}\x{2060}-\x{2064}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}\x{206A}-\x{206F}\x{207A}-\x{207B}\x{207C}\x{207D}\x{207E}\x{208A}-\x{208B}\x{208C}\x{208D}\x{208E}\x{20A0}-\x{20BF}\x{20C0}-\x{20CF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2100}-\x{2101}\x{2103}-\x{2106}\x{2108}-\x{2109}\x{2114}\x{2116}-\x{2117}\x{2118}\x{211E}-\x{2123}\x{2125}\x{2127}\x{2129}\x{212E}\x{213A}-\x{213B}\x{2140}-\x{2144}\x{214A}\x{214B}\x{214C}-\x{214D}\x{2150}-\x{215F}\x{2189}\x{218A}-\x{218B}\x{2190}-\x{2194}\x{2195}-\x{2199}\x{219A}-\x{219B}\x{219C}-\x{219F}\x{21A0}\x{21A1}-\x{21A2}\x{21A3}\x{21A4}-\x{21A5}\x{21A6}\x{21A7}-\x{21AD}\x{21AE}\x{21AF}-\x{21CD}\x{21CE}-\x{21CF}\x{21D0}-\x{21D1}\x{21D2}\x{21D3}\x{21D4}\x{21D5}-\x{21F3}\x{21F4}-\x{2211}\x{2212}\x{2213}\x{2214}-\x{22FF}\x{2300}-\x{2307}\x{2308}\x{2309}\x{230A}\x{230B}\x{230C}-\x{231F}\x{2320}-\x{2321}\x{2322}-\x{2328}\x{2329}\x{232A}\x{232B}-\x{2335}\x{237B}\x{237C}\x{237D}-\x{2394}\x{2396}-\x{239A}\x{239B}-\x{23B3}\x{23B4}-\x{23DB}\x{23DC}-\x{23E1}\x{23E2}-\x{2426}\x{2440}-\x{244A}\x{2460}-\x{2487}\x{24EA}-\x{24FF}\x{2500}-\x{25B6}\x{25B7}\x{25B8}-\x{25C0}\x{25C1}\x{25C2}-\x{25F7}\x{25F8}-\x{25FF}\x{2600}-\x{266E}\x{266F}\x{2670}-\x{26AB}\x{26AD}-\x{2767}\x{2768}\x{2769}\x{276A}\x{276B}\x{276C}\x{276D}\x{276E}\x{276F}\x{2770}\x{2771}\x{2772}\x{2773}\x{2774}\x{2775}\x{2776}-\x{2793}\x{2794}-\x{27BF}\x{27C0}-\x{27C4}\x{27C5}\x{27C6}\x{27C7}-\x{27E5}\x{27E6}\x{27E7}\x{27E8}\x{27E9}\x{27EA}\x{27EB}\x{27EC}\x{27ED}\x{27EE}\x{27EF}\x{27F0}-\x{27FF}\x{2900}-\x{2982}\x{2983}\x{2984}\x{2985}\x{2986}\x{2987}\x{2988}\x{2989}\x{298A}\x{298B}\x{298C}\x{298D}\x{298E}\x{298F}\x{2990}\x{2991}\x{2992}\x{2993}\x{2994}\x{2995}\x{2996}\x{2997}\x{2998}\x{2999}-\x{29D7}\x{29D8}\x{29D9}\x{29DA}\x{29DB}\x{29DC}-\x{29FB}\x{29FC}\x{29FD}\x{29FE}-\x{2AFF}\x{2B00}-\x{2B2F}\x{2B30}-\x{2B44}\x{2B45}-\x{2B46}\x{2B47}-\x{2B4C}\x{2B4D}-\x{2B73}\x{2B76}-\x{2B95}\x{2B97}-\x{2BFF}\x{2CE5}-\x{2CEA}\x{2CEF}-\x{2CF1}\x{2CF9}-\x{2CFC}\x{2CFD}\x{2CFE}-\x{2CFF}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E00}-\x{2E01}\x{2E02}\x{2E03}\x{2E04}\x{2E05}\x{2E06}-\x{2E08}\x{2E09}\x{2E0A}\x{2E0B}\x{2E0C}\x{2E0D}\x{2E0E}-\x{2E16}\x{2E17}\x{2E18}-\x{2E19}\x{2E1A}\x{2E1B}\x{2E1C}\x{2E1D}\x{2E1E}-\x{2E1F}\x{2E20}\x{2E21}\x{2E22}\x{2E23}\x{2E24}\x{2E25}\x{2E26}\x{2E27}\x{2E28}\x{2E29}\x{2E2A}-\x{2E2E}\x{2E2F}\x{2E30}-\x{2E39}\x{2E3A}-\x{2E3B}\x{2E3C}-\x{2E3F}\x{2E40}\x{2E41}\x{2E42}\x{2E43}-\x{2E4F}\x{2E50}-\x{2E51}\x{2E52}\x{2E80}-\x{2E99}\x{2E9B}-\x{2EF3}\x{2F00}-\x{2FD5}\x{2FF0}-\x{2FFB}\x{3000}\x{3001}-\x{3003}\x{3004}\x{3008}\x{3009}\x{300A}\x{300B}\x{300C}\x{300D}\x{300E}\x{300F}\x{3010}\x{3011}\x{3012}-\x{3013}\x{3014}\x{3015}\x{3016}\x{3017}\x{3018}\x{3019}\x{301A}\x{301B}\x{301C}\x{301D}\x{301E}-\x{301F}\x{3020}\x{302A}-\x{302D}\x{3030}\x{3036}-\x{3037}\x{303D}\x{303E}-\x{303F}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{30A0}\x{30FB}\x{31C0}-\x{31E3}\x{321D}-\x{321E}\x{3250}\x{3251}-\x{325F}\x{327C}-\x{327E}\x{32B1}-\x{32BF}\x{32CC}-\x{32CF}\x{3377}-\x{337A}\x{33DE}-\x{33DF}\x{33FF}\x{4DC0}-\x{4DFF}\x{A490}-\x{A4C6}\x{A60D}-\x{A60F}\x{A66F}\x{A670}-\x{A672}\x{A673}\x{A674}-\x{A67D}\x{A67E}\x{A67F}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A788}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A828}-\x{A82B}\x{A82C}\x{A838}\x{A839}\x{A874}-\x{A877}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{AB6A}-\x{AB6B}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1D}\x{FB1E}\x{FB1F}-\x{FB28}\x{FB29}\x{FB2A}-\x{FB36}\x{FB37}\x{FB38}-\x{FB3C}\x{FB3D}\x{FB3E}\x{FB3F}\x{FB40}-\x{FB41}\x{FB42}\x{FB43}-\x{FB44}\x{FB45}\x{FB46}-\x{FB4F}\x{FB50}-\x{FBB1}\x{FBB2}-\x{FBC1}\x{FBC2}-\x{FBD2}\x{FBD3}-\x{FD3D}\x{FD3E}\x{FD3F}\x{FD40}-\x{FD4F}\x{FD50}-\x{FD8F}\x{FD90}-\x{FD91}\x{FD92}-\x{FDC7}\x{FDC8}-\x{FDCF}\x{FDD0}-\x{FDEF}\x{FDF0}-\x{FDFB}\x{FDFC}\x{FDFD}\x{FDFE}-\x{FDFF}\x{FE00}-\x{FE0F}\x{FE10}-\x{FE16}\x{FE17}\x{FE18}\x{FE19}\x{FE20}-\x{FE2F}\x{FE30}\x{FE31}-\x{FE32}\x{FE33}-\x{FE34}\x{FE35}\x{FE36}\x{FE37}\x{FE38}\x{FE39}\x{FE3A}\x{FE3B}\x{FE3C}\x{FE3D}\x{FE3E}\x{FE3F}\x{FE40}\x{FE41}\x{FE42}\x{FE43}\x{FE44}\x{FE45}-\x{FE46}\x{FE47}\x{FE48}\x{FE49}-\x{FE4C}\x{FE4D}-\x{FE4F}\x{FE50}\x{FE51}\x{FE52}\x{FE54}\x{FE55}\x{FE56}-\x{FE57}\x{FE58}\x{FE59}\x{FE5A}\x{FE5B}\x{FE5C}\x{FE5D}\x{FE5E}\x{FE5F}\x{FE60}-\x{FE61}\x{FE62}\x{FE63}\x{FE64}-\x{FE66}\x{FE68}\x{FE69}\x{FE6A}\x{FE6B}\x{FE70}-\x{FE74}\x{FE75}\x{FE76}-\x{FEFC}\x{FEFD}-\x{FEFE}\x{FEFF}\x{FF01}-\x{FF02}\x{FF03}\x{FF04}\x{FF05}\x{FF06}-\x{FF07}\x{FF08}\x{FF09}\x{FF0A}\x{FF0B}\x{FF0C}\x{FF0D}\x{FF0E}-\x{FF0F}\x{FF1A}\x{FF1B}\x{FF1C}-\x{FF1E}\x{FF1F}-\x{FF20}\x{FF3B}\x{FF3C}\x{FF3D}\x{FF3E}\x{FF3F}\x{FF40}\x{FF5B}\x{FF5C}\x{FF5D}\x{FF5E}\x{FF5F}\x{FF60}\x{FF61}\x{FF62}\x{FF63}\x{FF64}-\x{FF65}\x{FFE0}-\x{FFE1}\x{FFE2}\x{FFE3}\x{FFE4}\x{FFE5}-\x{FFE6}\x{FFE8}\x{FFE9}-\x{FFEC}\x{FFED}-\x{FFEE}\x{FFF0}-\x{FFF8}\x{FFF9}-\x{FFFB}\x{FFFC}-\x{FFFD}\x{FFFE}-\x{FFFF}\x{10101}\x{10140}-\x{10174}\x{10175}-\x{10178}\x{10179}-\x{10189}\x{1018A}-\x{1018B}\x{1018C}\x{10190}-\x{1019C}\x{101A0}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10800}-\x{10805}\x{10806}-\x{10807}\x{10808}\x{10809}\x{1080A}-\x{10835}\x{10836}\x{10837}-\x{10838}\x{10839}-\x{1083B}\x{1083C}\x{1083D}-\x{1083E}\x{1083F}-\x{10855}\x{10856}\x{10857}\x{10858}-\x{1085F}\x{10860}-\x{10876}\x{10877}-\x{10878}\x{10879}-\x{1087F}\x{10880}-\x{1089E}\x{1089F}-\x{108A6}\x{108A7}-\x{108AF}\x{108B0}-\x{108DF}\x{108E0}-\x{108F2}\x{108F3}\x{108F4}-\x{108F5}\x{108F6}-\x{108FA}\x{108FB}-\x{108FF}\x{10900}-\x{10915}\x{10916}-\x{1091B}\x{1091C}-\x{1091E}\x{1091F}\x{10920}-\x{10939}\x{1093A}-\x{1093E}\x{1093F}\x{10940}-\x{1097F}\x{10980}-\x{109B7}\x{109B8}-\x{109BB}\x{109BC}-\x{109BD}\x{109BE}-\x{109BF}\x{109C0}-\x{109CF}\x{109D0}-\x{109D1}\x{109D2}-\x{109FF}\x{10A00}\x{10A01}-\x{10A03}\x{10A04}\x{10A05}-\x{10A06}\x{10A07}-\x{10A0B}\x{10A0C}-\x{10A0F}\x{10A10}-\x{10A13}\x{10A14}\x{10A15}-\x{10A17}\x{10A18}\x{10A19}-\x{10A35}\x{10A36}-\x{10A37}\x{10A38}-\x{10A3A}\x{10A3B}-\x{10A3E}\x{10A3F}\x{10A40}-\x{10A48}\x{10A49}-\x{10A4F}\x{10A50}-\x{10A58}\x{10A59}-\x{10A5F}\x{10A60}-\x{10A7C}\x{10A7D}-\x{10A7E}\x{10A7F}\x{10A80}-\x{10A9C}\x{10A9D}-\x{10A9F}\x{10AA0}-\x{10ABF}\x{10AC0}-\x{10AC7}\x{10AC8}\x{10AC9}-\x{10AE4}\x{10AE5}-\x{10AE6}\x{10AE7}-\x{10AEA}\x{10AEB}-\x{10AEF}\x{10AF0}-\x{10AF6}\x{10AF7}-\x{10AFF}\x{10B00}-\x{10B35}\x{10B36}-\x{10B38}\x{10B39}-\x{10B3F}\x{10B40}-\x{10B55}\x{10B56}-\x{10B57}\x{10B58}-\x{10B5F}\x{10B60}-\x{10B72}\x{10B73}-\x{10B77}\x{10B78}-\x{10B7F}\x{10B80}-\x{10B91}\x{10B92}-\x{10B98}\x{10B99}-\x{10B9C}\x{10B9D}-\x{10BA8}\x{10BA9}-\x{10BAF}\x{10BB0}-\x{10BFF}\x{10C00}-\x{10C48}\x{10C49}-\x{10C7F}\x{10C80}-\x{10CB2}\x{10CB3}-\x{10CBF}\x{10CC0}-\x{10CF2}\x{10CF3}-\x{10CF9}\x{10CFA}-\x{10CFF}\x{10D00}-\x{10D23}\x{10D24}-\x{10D27}\x{10D28}-\x{10D2F}\x{10D30}-\x{10D39}\x{10D3A}-\x{10D3F}\x{10D40}-\x{10E5F}\x{10E60}-\x{10E7E}\x{10E7F}\x{10E80}-\x{10EA9}\x{10EAA}\x{10EAB}-\x{10EAC}\x{10EAD}\x{10EAE}-\x{10EAF}\x{10EB0}-\x{10EB1}\x{10EB2}-\x{10EFF}\x{10F00}-\x{10F1C}\x{10F1D}-\x{10F26}\x{10F27}\x{10F28}-\x{10F2F}\x{10F30}-\x{10F45}\x{10F46}-\x{10F50}\x{10F51}-\x{10F54}\x{10F55}-\x{10F59}\x{10F5A}-\x{10F6F}\x{10F70}-\x{10FAF}\x{10FB0}-\x{10FC4}\x{10FC5}-\x{10FCB}\x{10FCC}-\x{10FDF}\x{10FE0}-\x{10FF6}\x{10FF7}-\x{10FFF}\x{11001}\x{11038}-\x{11046}\x{11052}-\x{11065}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{11660}-\x{1166C}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{11FD5}-\x{11FDC}\x{11FDD}-\x{11FE0}\x{11FE1}-\x{11FF1}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE2}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D200}-\x{1D241}\x{1D242}-\x{1D244}\x{1D245}\x{1D300}-\x{1D356}\x{1D6DB}\x{1D715}\x{1D74F}\x{1D789}\x{1D7C3}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E2FF}\x{1E800}-\x{1E8C4}\x{1E8C5}-\x{1E8C6}\x{1E8C7}-\x{1E8CF}\x{1E8D0}-\x{1E8D6}\x{1E8D7}-\x{1E8FF}\x{1E900}-\x{1E943}\x{1E944}-\x{1E94A}\x{1E94B}\x{1E94C}-\x{1E94F}\x{1E950}-\x{1E959}\x{1E95A}-\x{1E95D}\x{1E95E}-\x{1E95F}\x{1E960}-\x{1EC6F}\x{1EC70}\x{1EC71}-\x{1ECAB}\x{1ECAC}\x{1ECAD}-\x{1ECAF}\x{1ECB0}\x{1ECB1}-\x{1ECB4}\x{1ECB5}-\x{1ECBF}\x{1ECC0}-\x{1ECFF}\x{1ED00}\x{1ED01}-\x{1ED2D}\x{1ED2E}\x{1ED2F}-\x{1ED3D}\x{1ED3E}-\x{1ED4F}\x{1ED50}-\x{1EDFF}\x{1EE00}-\x{1EE03}\x{1EE04}\x{1EE05}-\x{1EE1F}\x{1EE20}\x{1EE21}-\x{1EE22}\x{1EE23}\x{1EE24}\x{1EE25}-\x{1EE26}\x{1EE27}\x{1EE28}\x{1EE29}-\x{1EE32}\x{1EE33}\x{1EE34}-\x{1EE37}\x{1EE38}\x{1EE39}\x{1EE3A}\x{1EE3B}\x{1EE3C}-\x{1EE41}\x{1EE42}\x{1EE43}-\x{1EE46}\x{1EE47}\x{1EE48}\x{1EE49}\x{1EE4A}\x{1EE4B}\x{1EE4C}\x{1EE4D}-\x{1EE4F}\x{1EE50}\x{1EE51}-\x{1EE52}\x{1EE53}\x{1EE54}\x{1EE55}-\x{1EE56}\x{1EE57}\x{1EE58}\x{1EE59}\x{1EE5A}\x{1EE5B}\x{1EE5C}\x{1EE5D}\x{1EE5E}\x{1EE5F}\x{1EE60}\x{1EE61}-\x{1EE62}\x{1EE63}\x{1EE64}\x{1EE65}-\x{1EE66}\x{1EE67}-\x{1EE6A}\x{1EE6B}\x{1EE6C}-\x{1EE72}\x{1EE73}\x{1EE74}-\x{1EE77}\x{1EE78}\x{1EE79}-\x{1EE7C}\x{1EE7D}\x{1EE7E}\x{1EE7F}\x{1EE80}-\x{1EE89}\x{1EE8A}\x{1EE8B}-\x{1EE9B}\x{1EE9C}-\x{1EEA0}\x{1EEA1}-\x{1EEA3}\x{1EEA4}\x{1EEA5}-\x{1EEA9}\x{1EEAA}\x{1EEAB}-\x{1EEBB}\x{1EEBC}-\x{1EEEF}\x{1EEF0}-\x{1EEF1}\x{1EEF2}-\x{1EEFF}\x{1EF00}-\x{1EFFF}\x{1F000}-\x{1F02B}\x{1F030}-\x{1F093}\x{1F0A0}-\x{1F0AE}\x{1F0B1}-\x{1F0BF}\x{1F0C1}-\x{1F0CF}\x{1F0D1}-\x{1F0F5}\x{1F10B}-\x{1F10C}\x{1F10D}-\x{1F10F}\x{1F12F}\x{1F16A}-\x{1F16F}\x{1F1AD}\x{1F260}-\x{1F265}\x{1F300}-\x{1F3FA}\x{1F3FB}-\x{1F3FF}\x{1F400}-\x{1F6D7}\x{1F6E0}-\x{1F6EC}\x{1F6F0}-\x{1F6FC}\x{1F700}-\x{1F773}\x{1F780}-\x{1F7D8}\x{1F7E0}-\x{1F7EB}\x{1F800}-\x{1F80B}\x{1F810}-\x{1F847}\x{1F850}-\x{1F859}\x{1F860}-\x{1F887}\x{1F890}-\x{1F8AD}\x{1F8B0}-\x{1F8B1}\x{1F900}-\x{1F978}\x{1F97A}-\x{1F9CB}\x{1F9CD}-\x{1FA53}\x{1FA60}-\x{1FA6D}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7A}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAA8}\x{1FAB0}-\x{1FAB6}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD6}\x{1FB00}-\x{1FB92}\x{1FB94}-\x{1FBCA}\x{1FFFE}-\x{1FFFF}\x{2FFFE}-\x{2FFFF}\x{3FFFE}-\x{3FFFF}\x{4FFFE}-\x{4FFFF}\x{5FFFE}-\x{5FFFF}\x{6FFFE}-\x{6FFFF}\x{7FFFE}-\x{7FFFF}\x{8FFFE}-\x{8FFFF}\x{9FFFE}-\x{9FFFF}\x{AFFFE}-\x{AFFFF}\x{BFFFE}-\x{BFFFF}\x{CFFFE}-\x{CFFFF}\x{DFFFE}-\x{E0000}\x{E0001}\x{E0002}-\x{E001F}\x{E0020}-\x{E007F}\x{E0080}-\x{E00FF}\x{E0100}-\x{E01EF}\x{E01F0}-\x{E0FFF}\x{EFFFE}-\x{EFFFF}\x{FFFFE}-\x{FFFFF}\x{10FFFE}-\x{10FFFF}][\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A06}\x{11A09}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1D167}-\x{1D169}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{E0100}-\x{E01EF}]*$/u'; - const ZWNJ = '/([\x{A872}\x{10ACD}\x{10AD7}\x{10D00}\x{10FCB}\x{0620}\x{0626}\x{0628}\x{062A}-\x{062E}\x{0633}-\x{063F}\x{0641}-\x{0647}\x{0649}-\x{064A}\x{066E}-\x{066F}\x{0678}-\x{0687}\x{069A}-\x{06BF}\x{06C1}-\x{06C2}\x{06CC}\x{06CE}\x{06D0}-\x{06D1}\x{06FA}-\x{06FC}\x{06FF}\x{0712}-\x{0714}\x{071A}-\x{071D}\x{071F}-\x{0727}\x{0729}\x{072B}\x{072D}-\x{072E}\x{074E}-\x{0758}\x{075C}-\x{076A}\x{076D}-\x{0770}\x{0772}\x{0775}-\x{0777}\x{077A}-\x{077F}\x{07CA}-\x{07EA}\x{0841}-\x{0845}\x{0848}\x{084A}-\x{0853}\x{0855}\x{0860}\x{0862}-\x{0865}\x{0868}\x{08A0}-\x{08A9}\x{08AF}-\x{08B0}\x{08B3}-\x{08B4}\x{08B6}-\x{08B8}\x{08BA}-\x{08C7}\x{1807}\x{1820}-\x{1842}\x{1843}\x{1844}-\x{1878}\x{1887}-\x{18A8}\x{18AA}\x{A840}-\x{A871}\x{10AC0}-\x{10AC4}\x{10AD3}-\x{10AD6}\x{10AD8}-\x{10ADC}\x{10ADE}-\x{10AE0}\x{10AEB}-\x{10AEE}\x{10B80}\x{10B82}\x{10B86}-\x{10B88}\x{10B8A}-\x{10B8B}\x{10B8D}\x{10B90}\x{10BAD}-\x{10BAE}\x{10D01}-\x{10D21}\x{10D23}\x{10F30}-\x{10F32}\x{10F34}-\x{10F44}\x{10F51}-\x{10F53}\x{10FB0}\x{10FB2}-\x{10FB3}\x{10FB8}\x{10FBB}-\x{10FBC}\x{10FBE}-\x{10FBF}\x{10FC1}\x{10FC4}\x{10FCA}\x{1E900}-\x{1E943}][\x{00AD}\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{061C}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{200B}\x{200E}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{206A}-\x{206F}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{FEFF}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{13430}-\x{13438}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1E94B}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}]*\x{200C}[\x{00AD}\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{061C}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{200B}\x{200E}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{206A}-\x{206F}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{FEFF}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{13430}-\x{13438}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1E94B}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}]*)[\x{0622}-\x{0625}\x{0627}\x{0629}\x{062F}-\x{0632}\x{0648}\x{0671}-\x{0673}\x{0675}-\x{0677}\x{0688}-\x{0699}\x{06C0}\x{06C3}-\x{06CB}\x{06CD}\x{06CF}\x{06D2}-\x{06D3}\x{06D5}\x{06EE}-\x{06EF}\x{0710}\x{0715}-\x{0719}\x{071E}\x{0728}\x{072A}\x{072C}\x{072F}\x{074D}\x{0759}-\x{075B}\x{076B}-\x{076C}\x{0771}\x{0773}-\x{0774}\x{0778}-\x{0779}\x{0840}\x{0846}-\x{0847}\x{0849}\x{0854}\x{0856}-\x{0858}\x{0867}\x{0869}-\x{086A}\x{08AA}-\x{08AC}\x{08AE}\x{08B1}-\x{08B2}\x{08B9}\x{10AC5}\x{10AC7}\x{10AC9}-\x{10ACA}\x{10ACE}-\x{10AD2}\x{10ADD}\x{10AE1}\x{10AE4}\x{10AEF}\x{10B81}\x{10B83}-\x{10B85}\x{10B89}\x{10B8C}\x{10B8E}-\x{10B8F}\x{10B91}\x{10BA9}-\x{10BAC}\x{10D22}\x{10F33}\x{10F54}\x{10FB4}-\x{10FB6}\x{10FB9}-\x{10FBA}\x{10FBD}\x{10FC2}-\x{10FC3}\x{10FC9}\x{0620}\x{0626}\x{0628}\x{062A}-\x{062E}\x{0633}-\x{063F}\x{0641}-\x{0647}\x{0649}-\x{064A}\x{066E}-\x{066F}\x{0678}-\x{0687}\x{069A}-\x{06BF}\x{06C1}-\x{06C2}\x{06CC}\x{06CE}\x{06D0}-\x{06D1}\x{06FA}-\x{06FC}\x{06FF}\x{0712}-\x{0714}\x{071A}-\x{071D}\x{071F}-\x{0727}\x{0729}\x{072B}\x{072D}-\x{072E}\x{074E}-\x{0758}\x{075C}-\x{076A}\x{076D}-\x{0770}\x{0772}\x{0775}-\x{0777}\x{077A}-\x{077F}\x{07CA}-\x{07EA}\x{0841}-\x{0845}\x{0848}\x{084A}-\x{0853}\x{0855}\x{0860}\x{0862}-\x{0865}\x{0868}\x{08A0}-\x{08A9}\x{08AF}-\x{08B0}\x{08B3}-\x{08B4}\x{08B6}-\x{08B8}\x{08BA}-\x{08C7}\x{1807}\x{1820}-\x{1842}\x{1843}\x{1844}-\x{1878}\x{1887}-\x{18A8}\x{18AA}\x{A840}-\x{A871}\x{10AC0}-\x{10AC4}\x{10AD3}-\x{10AD6}\x{10AD8}-\x{10ADC}\x{10ADE}-\x{10AE0}\x{10AEB}-\x{10AEE}\x{10B80}\x{10B82}\x{10B86}-\x{10B88}\x{10B8A}-\x{10B8B}\x{10B8D}\x{10B90}\x{10BAD}-\x{10BAE}\x{10D01}-\x{10D21}\x{10D23}\x{10F30}-\x{10F32}\x{10F34}-\x{10F44}\x{10F51}-\x{10F53}\x{10FB0}\x{10FB2}-\x{10FB3}\x{10FB8}\x{10FBB}-\x{10FBC}\x{10FBE}-\x{10FBF}\x{10FC1}\x{10FC4}\x{10FCA}\x{1E900}-\x{1E943}]/u'; + public const ZWNJ = '/([\x{A872}\x{10ACD}\x{10AD7}\x{10D00}\x{10FCB}\x{0620}\x{0626}\x{0628}\x{062A}-\x{062E}\x{0633}-\x{063F}\x{0641}-\x{0647}\x{0649}-\x{064A}\x{066E}-\x{066F}\x{0678}-\x{0687}\x{069A}-\x{06BF}\x{06C1}-\x{06C2}\x{06CC}\x{06CE}\x{06D0}-\x{06D1}\x{06FA}-\x{06FC}\x{06FF}\x{0712}-\x{0714}\x{071A}-\x{071D}\x{071F}-\x{0727}\x{0729}\x{072B}\x{072D}-\x{072E}\x{074E}-\x{0758}\x{075C}-\x{076A}\x{076D}-\x{0770}\x{0772}\x{0775}-\x{0777}\x{077A}-\x{077F}\x{07CA}-\x{07EA}\x{0841}-\x{0845}\x{0848}\x{084A}-\x{0853}\x{0855}\x{0860}\x{0862}-\x{0865}\x{0868}\x{08A0}-\x{08A9}\x{08AF}-\x{08B0}\x{08B3}-\x{08B4}\x{08B6}-\x{08B8}\x{08BA}-\x{08C7}\x{1807}\x{1820}-\x{1842}\x{1843}\x{1844}-\x{1878}\x{1887}-\x{18A8}\x{18AA}\x{A840}-\x{A871}\x{10AC0}-\x{10AC4}\x{10AD3}-\x{10AD6}\x{10AD8}-\x{10ADC}\x{10ADE}-\x{10AE0}\x{10AEB}-\x{10AEE}\x{10B80}\x{10B82}\x{10B86}-\x{10B88}\x{10B8A}-\x{10B8B}\x{10B8D}\x{10B90}\x{10BAD}-\x{10BAE}\x{10D01}-\x{10D21}\x{10D23}\x{10F30}-\x{10F32}\x{10F34}-\x{10F44}\x{10F51}-\x{10F53}\x{10FB0}\x{10FB2}-\x{10FB3}\x{10FB8}\x{10FBB}-\x{10FBC}\x{10FBE}-\x{10FBF}\x{10FC1}\x{10FC4}\x{10FCA}\x{1E900}-\x{1E943}][\x{00AD}\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{061C}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{200B}\x{200E}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{206A}-\x{206F}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{FEFF}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{13430}-\x{13438}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1E94B}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}]*\x{200C}[\x{00AD}\x{0300}-\x{036F}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{0610}-\x{061A}\x{061C}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DF}-\x{06E4}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07FD}\x{0816}-\x{0819}\x{081B}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B55}-\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0D81}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EBC}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17DD}\x{180B}-\x{180D}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1ABF}-\x{1AC0}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{200B}\x{200E}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{206A}-\x{206F}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2CEF}-\x{2CF1}\x{2D7F}\x{2DE0}-\x{2DFF}\x{302A}-\x{302D}\x{3099}-\x{309A}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A82C}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}-\x{A9BD}\x{A9E5}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AAEC}-\x{AAED}\x{AAF6}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FE00}-\x{FE0F}\x{FE20}-\x{FE2F}\x{FEFF}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10EAB}-\x{10EAC}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{111CF}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{1193B}-\x{1193C}\x{1193E}\x{11943}\x{119D4}-\x{119D7}\x{119DA}-\x{119DB}\x{119E0}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{13430}-\x{13438}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16F4F}\x{16F8F}-\x{16F92}\x{16FE4}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E130}-\x{1E136}\x{1E2EC}-\x{1E2EF}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1E94B}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}]*)[\x{0622}-\x{0625}\x{0627}\x{0629}\x{062F}-\x{0632}\x{0648}\x{0671}-\x{0673}\x{0675}-\x{0677}\x{0688}-\x{0699}\x{06C0}\x{06C3}-\x{06CB}\x{06CD}\x{06CF}\x{06D2}-\x{06D3}\x{06D5}\x{06EE}-\x{06EF}\x{0710}\x{0715}-\x{0719}\x{071E}\x{0728}\x{072A}\x{072C}\x{072F}\x{074D}\x{0759}-\x{075B}\x{076B}-\x{076C}\x{0771}\x{0773}-\x{0774}\x{0778}-\x{0779}\x{0840}\x{0846}-\x{0847}\x{0849}\x{0854}\x{0856}-\x{0858}\x{0867}\x{0869}-\x{086A}\x{08AA}-\x{08AC}\x{08AE}\x{08B1}-\x{08B2}\x{08B9}\x{10AC5}\x{10AC7}\x{10AC9}-\x{10ACA}\x{10ACE}-\x{10AD2}\x{10ADD}\x{10AE1}\x{10AE4}\x{10AEF}\x{10B81}\x{10B83}-\x{10B85}\x{10B89}\x{10B8C}\x{10B8E}-\x{10B8F}\x{10B91}\x{10BA9}-\x{10BAC}\x{10D22}\x{10F33}\x{10F54}\x{10FB4}-\x{10FB6}\x{10FB9}-\x{10FBA}\x{10FBD}\x{10FC2}-\x{10FC3}\x{10FC9}\x{0620}\x{0626}\x{0628}\x{062A}-\x{062E}\x{0633}-\x{063F}\x{0641}-\x{0647}\x{0649}-\x{064A}\x{066E}-\x{066F}\x{0678}-\x{0687}\x{069A}-\x{06BF}\x{06C1}-\x{06C2}\x{06CC}\x{06CE}\x{06D0}-\x{06D1}\x{06FA}-\x{06FC}\x{06FF}\x{0712}-\x{0714}\x{071A}-\x{071D}\x{071F}-\x{0727}\x{0729}\x{072B}\x{072D}-\x{072E}\x{074E}-\x{0758}\x{075C}-\x{076A}\x{076D}-\x{0770}\x{0772}\x{0775}-\x{0777}\x{077A}-\x{077F}\x{07CA}-\x{07EA}\x{0841}-\x{0845}\x{0848}\x{084A}-\x{0853}\x{0855}\x{0860}\x{0862}-\x{0865}\x{0868}\x{08A0}-\x{08A9}\x{08AF}-\x{08B0}\x{08B3}-\x{08B4}\x{08B6}-\x{08B8}\x{08BA}-\x{08C7}\x{1807}\x{1820}-\x{1842}\x{1843}\x{1844}-\x{1878}\x{1887}-\x{18A8}\x{18AA}\x{A840}-\x{A871}\x{10AC0}-\x{10AC4}\x{10AD3}-\x{10AD6}\x{10AD8}-\x{10ADC}\x{10ADE}-\x{10AE0}\x{10AEB}-\x{10AEE}\x{10B80}\x{10B82}\x{10B86}-\x{10B88}\x{10B8A}-\x{10B8B}\x{10B8D}\x{10B90}\x{10BAD}-\x{10BAE}\x{10D01}-\x{10D21}\x{10D23}\x{10F30}-\x{10F32}\x{10F34}-\x{10F44}\x{10F51}-\x{10F53}\x{10FB0}\x{10FB2}-\x{10FB3}\x{10FB8}\x{10FBB}-\x{10FBC}\x{10FBE}-\x{10FBF}\x{10FC1}\x{10FC4}\x{10FCA}\x{1E900}-\x{1E943}]/u'; } diff --git a/vendor/symfony/polyfill-intl-idn/bootstrap.php b/vendor/symfony/polyfill-intl-idn/bootstrap.php index f02d5de73..57c78356c 100644 --- a/vendor/symfony/polyfill-intl-idn/bootstrap.php +++ b/vendor/symfony/polyfill-intl-idn/bootstrap.php @@ -15,6 +15,10 @@ if (extension_loaded('intl')) { return; } +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + if (!defined('U_IDNA_PROHIBITED_ERROR')) { define('U_IDNA_PROHIBITED_ERROR', 66560); } @@ -124,18 +128,18 @@ if (!defined('IDNA_ERROR_CONTEXTJ')) { define('IDNA_ERROR_CONTEXTJ', 4096); } -if (PHP_VERSION_ID < 70400) { +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); } + function idn_to_ascii($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_2003, &$idna_info = null) { return p\Idn::idn_to_ascii($domain, $flags, $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); } + function idn_to_utf8($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_2003, &$idna_info = null) { return p\Idn::idn_to_utf8($domain, $flags, $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); } + function idn_to_ascii($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) { return p\Idn::idn_to_ascii($domain, $flags, $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); } + function idn_to_utf8($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) { return p\Idn::idn_to_utf8($domain, $flags, $variant, $idna_info); } } } diff --git a/vendor/symfony/polyfill-intl-idn/bootstrap80.php b/vendor/symfony/polyfill-intl-idn/bootstrap80.php index 6c2b72923..896538697 100644 --- a/vendor/symfony/polyfill-intl-idn/bootstrap80.php +++ b/vendor/symfony/polyfill-intl-idn/bootstrap80.php @@ -121,8 +121,8 @@ if (!defined('IDNA_ERROR_CONTEXTJ')) { } if (!function_exists('idn_to_ascii')) { - function idn_to_ascii(string $domain, int $flags = 0, int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_ascii($domain, $flags, $variant, $idna_info); } + function idn_to_ascii(?string $domain, ?int $flags = 0, ?int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_ascii((string) $domain, (int) $flags, (int) $variant, $idna_info); } } if (!function_exists('idn_to_utf8')) { - function idn_to_utf8(string $domain, int $flags = 0, int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_utf8($domain, $flags, $variant, $idna_info); } + function idn_to_utf8(?string $domain, ?int $flags = 0, ?int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_utf8((string) $domain, (int) $flags, (int) $variant, $idna_info); } } diff --git a/vendor/symfony/polyfill-intl-idn/composer.json b/vendor/symfony/polyfill-intl-idn/composer.json index bd89e6ed7..450d1e7b2 100644 --- a/vendor/symfony/polyfill-intl-idn/composer.json +++ b/vendor/symfony/polyfill-intl-idn/composer.json @@ -20,9 +20,8 @@ } ], "require": { - "php": ">=5.3.3", + "php": ">=7.1", "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php70": "^1.10", "symfony/polyfill-php72": "^1.10" }, "autoload": { @@ -35,7 +34,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", diff --git a/vendor/symfony/polyfill-intl-normalizer/Normalizer.php b/vendor/symfony/polyfill-intl-normalizer/Normalizer.php index a60fae620..4443c2322 100644 --- a/vendor/symfony/polyfill-intl-normalizer/Normalizer.php +++ b/vendor/symfony/polyfill-intl-normalizer/Normalizer.php @@ -23,28 +23,27 @@ namespace Symfony\Polyfill\Intl\Normalizer; */ class Normalizer { - const FORM_D = \Normalizer::FORM_D; - const FORM_KD = \Normalizer::FORM_KD; - const FORM_C = \Normalizer::FORM_C; - const FORM_KC = \Normalizer::FORM_KC; - const NFD = \Normalizer::NFD; - const NFKD = \Normalizer::NFKD; - const NFC = \Normalizer::NFC; - const NFKC = \Normalizer::NFKC; + public const FORM_D = \Normalizer::FORM_D; + public const FORM_KD = \Normalizer::FORM_KD; + public const FORM_C = \Normalizer::FORM_C; + public const FORM_KC = \Normalizer::FORM_KC; + public const NFD = \Normalizer::NFD; + public const NFKD = \Normalizer::NFKD; + public const NFC = \Normalizer::NFC; + public const NFKC = \Normalizer::NFKC; private static $C; private static $D; private static $KD; private static $cC; - private static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4); + private static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; private static $ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; - public static function isNormalized($s, $form = self::NFC) + public static function isNormalized(string $s, int $form = self::FORM_C) { - if (!\in_array($form, array(self::NFD, self::NFKD, self::NFC, self::NFKC))) { + if (!\in_array($form, [self::NFD, self::NFKD, self::NFC, self::NFKC])) { return false; } - $s = (string) $s; if (!isset($s[strspn($s, self::$ASCII)])) { return true; } @@ -55,9 +54,8 @@ class Normalizer return self::normalize($s, $form) === $s; } - public static function normalize($s, $form = self::NFC) + public static function normalize(string $s, int $form = self::FORM_C) { - $s = (string) $s; if (!preg_match('//u', $s)) { return false; } @@ -72,7 +70,11 @@ class Normalizer return $s; } - return false; + if (80000 > \PHP_VERSION_ID) { + return false; + } + + throw new \ValueError('normalizer_normalize(): Argument #2 ($form) must be a a valid normalization form'); } if ('' === $s) { @@ -152,7 +154,7 @@ class Normalizer || $lastUcls) { // Table lookup and combining chars composition - $ucls = isset($combClass[$uchr]) ? $combClass[$uchr] : 0; + $ucls = $combClass[$uchr] ?? 0; if (isset($compMap[$lastUchr.$uchr]) && (!$lastUcls || $lastUcls < $ucls)) { $lastUchr = $compMap[$lastUchr.$uchr]; @@ -204,7 +206,7 @@ class Normalizer $compatMap = self::$KD; } - $c = array(); + $c = []; $i = 0; $len = \strlen($s); @@ -215,7 +217,7 @@ class Normalizer if ($c) { ksort($c); $result .= implode('', $c); - $c = array(); + $c = []; } $j = 1 + strspn($s, $ASCII, $i + 1); @@ -231,7 +233,7 @@ class Normalizer if ($uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr) { // Table lookup - if ($uchr !== $j = isset($compatMap[$uchr]) ? $compatMap[$uchr] : (isset($decompMap[$uchr]) ? $decompMap[$uchr] : $uchr)) { + if ($uchr !== $j = $compatMap[$uchr] ?? ($decompMap[$uchr] ?? $uchr)) { $uchr = $j; $j = \strlen($uchr); @@ -283,7 +285,7 @@ class Normalizer if ($c) { ksort($c); $result .= implode('', $c); - $c = array(); + $c = []; } $result .= $uchr; diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php b/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php index ca18eff36..0fdfc890a 100644 --- a/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php +++ b/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php @@ -5,13 +5,13 @@ class Normalizer extends Symfony\Polyfill\Intl\Normalizer\Normalizer /** * @deprecated since ICU 56 and removed in PHP 8 */ - const NONE = 1; - const FORM_D = 2; - const FORM_KD = 3; - const FORM_C = 4; - const FORM_KC = 5; - const NFD = 2; - const NFKD = 3; - const NFC = 4; - const NFKC = 5; + public const NONE = 2; + public const FORM_D = 4; + public const FORM_KD = 8; + public const FORM_C = 16; + public const FORM_KC = 32; + public const NFD = 4; + public const NFKD = 8; + public const NFC = 16; + public const NFKC = 32; } diff --git a/vendor/symfony/polyfill-intl-normalizer/bootstrap.php b/vendor/symfony/polyfill-intl-normalizer/bootstrap.php index bac4318c9..3608e5c05 100644 --- a/vendor/symfony/polyfill-intl-normalizer/bootstrap.php +++ b/vendor/symfony/polyfill-intl-normalizer/bootstrap.php @@ -11,9 +11,13 @@ use Symfony\Polyfill\Intl\Normalizer as p; +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + if (!function_exists('normalizer_is_normalized')) { - function normalizer_is_normalized($input, $form = p\Normalizer::NFC) { return p\Normalizer::isNormalized($input, $form); } + function normalizer_is_normalized($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::isNormalized($string, $form); } } if (!function_exists('normalizer_normalize')) { - function normalizer_normalize($input, $form = p\Normalizer::NFC) { return p\Normalizer::normalize($input, $form); } + function normalizer_normalize($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::normalize($string, $form); } } diff --git a/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php b/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php index c9a29d7a9..e36d1a947 100644 --- a/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php +++ b/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php @@ -12,8 +12,8 @@ use Symfony\Polyfill\Intl\Normalizer as p; if (!function_exists('normalizer_is_normalized')) { - function normalizer_is_normalized(string $string, int $form = p\Normalizer::FORM_C): bool { return p\Normalizer::isNormalized($string, $form); } + function normalizer_is_normalized(?string $string, ?int $form = p\Normalizer::FORM_C): bool { return p\Normalizer::isNormalized((string) $string, (int) $form); } } if (!function_exists('normalizer_normalize')) { - function normalizer_normalize(string $string, int $form = p\Normalizer::FORM_C): string|false { return p\Normalizer::normalize($string, $form); } + function normalizer_normalize(?string $string, ?int $form = p\Normalizer::FORM_C): string|false { return p\Normalizer::normalize((string) $string, (int) $form); } } diff --git a/vendor/symfony/polyfill-intl-normalizer/composer.json b/vendor/symfony/polyfill-intl-normalizer/composer.json index 8df2fa1e6..8f4cfb4dc 100644 --- a/vendor/symfony/polyfill-intl-normalizer/composer.json +++ b/vendor/symfony/polyfill-intl-normalizer/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, @@ -29,7 +29,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", diff --git a/vendor/symfony/polyfill-mbstring/Mbstring.php b/vendor/symfony/polyfill-mbstring/Mbstring.php index dc7801f4c..8b3b75893 100644 --- a/vendor/symfony/polyfill-mbstring/Mbstring.php +++ b/vendor/symfony/polyfill-mbstring/Mbstring.php @@ -67,15 +67,15 @@ namespace Symfony\Polyfill\Mbstring; */ final class Mbstring { - const MB_CASE_FOLD = PHP_INT_MAX; + public const MB_CASE_FOLD = \PHP_INT_MAX; - private static $encodingList = array('ASCII', 'UTF-8'); + private static $encodingList = ['ASCII', 'UTF-8']; private static $language = 'neutral'; private static $internalEncoding = 'UTF-8'; - private static $caseFold = array( - array('µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"), - array('μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'), - ); + private static $caseFold = [ + ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"], + ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'], + ]; public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) { @@ -104,24 +104,22 @@ final class Mbstring $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s); } - return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s); + return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s); } if ('HTML-ENTITIES' === $fromEncoding) { - $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8'); + $s = html_entity_decode($s, \ENT_COMPAT, 'UTF-8'); $fromEncoding = 'UTF-8'; } return iconv($fromEncoding, $toEncoding.'//IGNORE', $s); } - public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) + public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars) { - $vars = array(&$a, &$b, &$c, &$d, &$e, &$f); - $ok = true; array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) { - if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) { + if (false === $v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding)) { $ok = false; } }); @@ -136,23 +134,23 @@ final class Mbstring public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null) { - trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING); + trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING); } public static function mb_decode_numericentity($s, $convmap, $encoding = null) { - if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) { - trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING); + if (null !== $s && !is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { + trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING); return null; } - if (!\is_array($convmap) || !$convmap) { + if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) { return false; } - if (null !== $encoding && !\is_scalar($encoding)) { - trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING); + if (null !== $encoding && !is_scalar($encoding)) { + trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING); return ''; // Instead of null (cf. mb_encode_numericentity). } @@ -185,7 +183,7 @@ final class Mbstring $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1]; for ($i = 0; $i < $cnt; $i += 4) { if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) { - return Mbstring::mb_chr($c - $convmap[$i + 2]); + return self::mb_chr($c - $convmap[$i + 2]); } } @@ -201,24 +199,24 @@ final class Mbstring public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false) { - if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) { - trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING); + if (null !== $s && !is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { + trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING); return null; } - if (!\is_array($convmap) || !$convmap) { + if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) { return false; } - if (null !== $encoding && !\is_scalar($encoding)) { - trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING); + if (null !== $encoding && !is_scalar($encoding)) { + trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING); return null; // Instead of '' (cf. mb_decode_numericentity). } - if (null !== $is_hex && !\is_scalar($is_hex)) { - trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', E_USER_WARNING); + if (null !== $is_hex && !is_scalar($is_hex)) { + trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', \E_USER_WARNING); return null; } @@ -239,7 +237,7 @@ final class Mbstring $s = iconv($encoding, 'UTF-8//IGNORE', $s); } - static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4); + static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; $cnt = floor(\count($convmap) / 4) * 4; $i = 0; @@ -287,14 +285,14 @@ final class Mbstring $s = iconv($encoding, 'UTF-8//IGNORE', $s); } - if (MB_CASE_TITLE == $mode) { + if (\MB_CASE_TITLE == $mode) { static $titleRegexp = null; if (null === $titleRegexp) { $titleRegexp = self::getData('titleCaseRegexp'); } - $s = preg_replace_callback($titleRegexp, array(__CLASS__, 'title_case'), $s); + $s = preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s); } else { - if (MB_CASE_UPPER == $mode) { + if (\MB_CASE_UPPER == $mode) { static $upper = null; if (null === $upper) { $upper = self::getData('upperCase'); @@ -312,7 +310,7 @@ final class Mbstring $map = $lower; } - static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4); + static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; $i = 0; $len = \strlen($s); @@ -353,15 +351,19 @@ final class Mbstring return self::$internalEncoding; } - $encoding = self::getEncoding($encoding); + $normalizedEncoding = self::getEncoding($encoding); - if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) { - self::$internalEncoding = $encoding; + if ('UTF-8' === $normalizedEncoding || false !== @iconv($normalizedEncoding, $normalizedEncoding, ' ')) { + self::$internalEncoding = $normalizedEncoding; return true; } - return false; + if (80000 > \PHP_VERSION_ID) { + return false; + } + + throw new \ValueError(sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding)); } public static function mb_language($lang = null) @@ -370,20 +372,24 @@ final class Mbstring return self::$language; } - switch ($lang = strtolower($lang)) { + switch ($normalizedLang = strtolower($lang)) { case 'uni': case 'neutral': - self::$language = $lang; + self::$language = $normalizedLang; return true; } - return false; + if (80000 > \PHP_VERSION_ID) { + return false; + } + + throw new \ValueError(sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang)); } public static function mb_list_encodings() { - return array('UTF-8'); + return ['UTF-8']; } public static function mb_encoding_aliases($encoding) @@ -391,7 +397,7 @@ final class Mbstring switch (strtoupper($encoding)) { case 'UTF8': case 'UTF-8': - return array('utf8'); + return ['utf8']; } return false; @@ -406,7 +412,7 @@ final class Mbstring $encoding = self::$internalEncoding; } - return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var); + return self::mb_detect_encoding($var, [$encoding]) || false !== @iconv($encoding, $encoding, $var); } public static function mb_detect_encoding($str, $encodingList = null, $strict = false) @@ -493,9 +499,13 @@ final class Mbstring $needle = (string) $needle; if ('' === $needle) { - trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING); + if (80000 > \PHP_VERSION_ID) { + trigger_error(__METHOD__.': Empty delimiter', \E_USER_WARNING); - return false; + return false; + } + + return 0; } return iconv_strpos($haystack, $needle, $offset, $encoding); @@ -521,23 +531,28 @@ final class Mbstring } } - $pos = iconv_strrpos($haystack, $needle, $encoding); + $pos = '' !== $needle || 80000 > \PHP_VERSION_ID + ? iconv_strrpos($haystack, $needle, $encoding) + : self::mb_strlen($haystack, $encoding); return false !== $pos ? $offset + $pos : false; } public static function mb_str_split($string, $split_length = 1, $encoding = null) { - if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) { - trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', E_USER_WARNING); + if (null !== $string && !is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) { + trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', \E_USER_WARNING); return null; } if (1 > $split_length = (int) $split_length) { - trigger_error('The length of each segment must be greater than zero', E_USER_WARNING); + if (80000 > \PHP_VERSION_ID) { + trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING); + return false; + } - return false; + throw new \ValueError('Argument #2 ($length) must be greater than 0'); } if (null === $encoding) { @@ -552,10 +567,10 @@ final class Mbstring } $rx .= '.{'.$split_length.'})/us'; - return preg_split($rx, $string, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + return preg_split($rx, $string, null, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY); } - $result = array(); + $result = []; $length = mb_strlen($string, $encoding); for ($i = 0; $i < $length; $i += $split_length) { @@ -567,21 +582,27 @@ final class Mbstring public static function mb_strtolower($s, $encoding = null) { - return self::mb_convert_case($s, MB_CASE_LOWER, $encoding); + return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding); } public static function mb_strtoupper($s, $encoding = null) { - return self::mb_convert_case($s, MB_CASE_UPPER, $encoding); + return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding); } public static function mb_substitute_character($c = null) { + if (null === $c) { + return 'none'; + } if (0 === strcasecmp($c, 'none')) { return true; } + if (80000 > \PHP_VERSION_ID) { + return false; + } - return null !== $c ? false : 'none'; + throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint'); } public static function mb_substr($s, $start, $length = null, $encoding = null) @@ -669,7 +690,7 @@ final class Mbstring public static function mb_get_info($type = 'all') { - $info = array( + $info = [ 'internal_encoding' => self::$internalEncoding, 'http_output' => 'pass', 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)', @@ -684,7 +705,7 @@ final class Mbstring 'detect_order' => self::$encodingList, 'substitute_character' => 'none', 'strict_detection' => 'Off', - ); + ]; if ('all' === $type) { return $info; @@ -788,7 +809,7 @@ final class Mbstring { $i = 1; $entities = ''; - $m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8')); + $m = unpack('C*', htmlentities($m[0], \ENT_COMPAT, 'UTF-8')); while (isset($m[$i])) { if (0x80 > $m[$i]) { @@ -811,7 +832,7 @@ final class Mbstring private static function title_case(array $s) { - return self::mb_convert_case($s[1], MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], MB_CASE_LOWER, 'UTF-8'); + return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8'); } private static function getData($file) diff --git a/vendor/symfony/polyfill-mbstring/bootstrap.php b/vendor/symfony/polyfill-mbstring/bootstrap.php index a48f7e62e..c45624c9f 100644 --- a/vendor/symfony/polyfill-mbstring/bootstrap.php +++ b/vendor/symfony/polyfill-mbstring/bootstrap.php @@ -11,6 +11,10 @@ use Symfony\Polyfill\Mbstring as p; +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + if (!function_exists('mb_convert_encoding')) { function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); } } @@ -18,7 +22,7 @@ if (!function_exists('mb_decode_mimeheader')) { function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); } } if (!function_exists('mb_encode_mimeheader')) { - function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); } + function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); } } if (!function_exists('mb_decode_numericentity')) { function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); } @@ -51,7 +55,7 @@ if (!function_exists('mb_detect_order')) { function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); } } if (!function_exists('mb_parse_str')) { - function mb_parse_str($string, &$result = array()) { parse_str($string, $result); } + function mb_parse_str($string, &$result = []) { parse_str($string, $result); } } if (!function_exists('mb_strlen')) { function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); } @@ -108,13 +112,11 @@ if (!function_exists('mb_output_handler')) { function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); } } if (!function_exists('mb_http_input')) { - function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); } + function mb_http_input($type = null) { return p\Mbstring::mb_http_input($type); } } -if (PHP_VERSION_ID >= 80000) { - require_once __DIR__.'/Resources/mb_convert_variables.php8'; -} elseif (!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_convert_variables')) { + function mb_convert_variables($to_encoding, $from_encoding, &...$vars) { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars); } } if (!function_exists('mb_ord')) { diff --git a/vendor/symfony/polyfill-mbstring/bootstrap80.php b/vendor/symfony/polyfill-mbstring/bootstrap80.php index e86754e52..f404f5fea 100644 --- a/vendor/symfony/polyfill-mbstring/bootstrap80.php +++ b/vendor/symfony/polyfill-mbstring/bootstrap80.php @@ -12,120 +12,120 @@ use Symfony\Polyfill\Mbstring as p; if (!function_exists('mb_convert_encoding')) { - function mb_convert_encoding(array|string $string, string $to_encoding, array|string|null $from_encoding = null): array|string|false { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); } + function mb_convert_encoding(array|string|null $string, ?string $to_encoding, array|string|null $from_encoding = null): array|string|false { return p\Mbstring::mb_convert_encoding($string ?? '', (string) $to_encoding, $from_encoding); } } if (!function_exists('mb_decode_mimeheader')) { - function mb_decode_mimeheader(string $string): string { return p\Mbstring::mb_decode_mimeheader($string); } + function mb_decode_mimeheader(?string $string): string { return p\Mbstring::mb_decode_mimeheader((string) $string); } } if (!function_exists('mb_encode_mimeheader')) { - function mb_encode_mimeheader(string $string, string $charset = null, string $transfer_encoding = null, string $newline = "\r\n", int $indent = 0): string { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); } + function mb_encode_mimeheader(?string $string, ?string $charset = null, ?string $transfer_encoding = null, ?string $newline = "\r\n", ?int $indent = 0): string { return p\Mbstring::mb_encode_mimeheader((string) $string, $charset, $transfer_encoding, (string) $newline, (int) $indent); } } if (!function_exists('mb_decode_numericentity')) { - function mb_decode_numericentity(string $string, array $map, string $encoding = null): string { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); } + function mb_decode_numericentity(?string $string, array $map, ?string $encoding = null): string { return p\Mbstring::mb_decode_numericentity((string) $string, $map, $encoding); } } if (!function_exists('mb_encode_numericentity')) { - function mb_encode_numericentity(string $string, array $map, string $encoding = null, bool $hex = false): string { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); } + function mb_encode_numericentity(?string $string, array $map, ?string $encoding = null, ?bool $hex = false): string { return p\Mbstring::mb_encode_numericentity((string) $string, $map, $encoding, (bool) $hex); } } if (!function_exists('mb_convert_case')) { - function mb_convert_case(string $string, int $mode, string $encoding = null): string { return p\Mbstring::mb_convert_case($string, $mode, $encoding); } + function mb_convert_case(?string $string, ?int $mode, ?string $encoding = null): string { return p\Mbstring::mb_convert_case((string) $string, (int) $mode, $encoding); } } if (!function_exists('mb_internal_encoding')) { - function mb_internal_encoding(string $encoding = null): string|bool { return p\Mbstring::mb_internal_encoding($encoding); } + function mb_internal_encoding(?string $encoding = null): string|bool { return p\Mbstring::mb_internal_encoding($encoding); } } if (!function_exists('mb_language')) { - function mb_language(string $language = null): string|bool { return p\Mbstring::mb_language($language); } + function mb_language(?string $language = null): string|bool { return p\Mbstring::mb_language($language); } } if (!function_exists('mb_list_encodings')) { function mb_list_encodings(): array { return p\Mbstring::mb_list_encodings(); } } if (!function_exists('mb_encoding_aliases')) { - function mb_encoding_aliases(string $encoding): array { return p\Mbstring::mb_encoding_aliases($encoding); } + function mb_encoding_aliases(?string $encoding): array { return p\Mbstring::mb_encoding_aliases((string) $encoding); } } if (!function_exists('mb_check_encoding')) { - function mb_check_encoding(array|string|null $value = null, string $encoding = null): bool { return p\Mbstring::mb_check_encoding($value, $encoding); } + function mb_check_encoding(array|string|null $value = null, ?string $encoding = null): bool { return p\Mbstring::mb_check_encoding($value, $encoding); } } if (!function_exists('mb_detect_encoding')) { - function mb_detect_encoding(string $string, array|string|null $encodings = null, bool $strict = false): string|false { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); } + function mb_detect_encoding(?string $string, array|string|null $encodings = null, ?bool $strict = false): string|false { return p\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict); } } if (!function_exists('mb_detect_order')) { - function mb_detect_order(array|string|null $encoding = null): array|bool { return p\Mbstring::mb_detect_order($encoding); } + function mb_detect_order(array|string|null $encoding = null): array|bool { return p\Mbstring::mb_detect_order((string) $encoding); } } if (!function_exists('mb_parse_str')) { - function mb_parse_str(string $string, &$result = array()): bool { parse_str($string, $result); } + function mb_parse_str(?string $string, &$result = []): bool { parse_str((string) $string, $result); } } if (!function_exists('mb_strlen')) { - function mb_strlen(string $string, string $encoding = null): int { return p\Mbstring::mb_strlen($string, $encoding); } + function mb_strlen(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strlen((string) $string, $encoding); } } if (!function_exists('mb_strpos')) { - function mb_strpos(string $haystack, string $needle, int $offset = 0, string $encoding = null): int|false { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); } + function mb_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } } if (!function_exists('mb_strtolower')) { - function mb_strtolower(string $string, string $encoding = null): string { return p\Mbstring::mb_strtolower($string, $encoding); } + function mb_strtolower(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtolower((string) $string, $encoding); } } if (!function_exists('mb_strtoupper')) { - function mb_strtoupper(string $string, string $encoding = null): string { return p\Mbstring::mb_strtoupper($string, $encoding); } + function mb_strtoupper(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtoupper((string) $string, $encoding); } } if (!function_exists('mb_substitute_character')) { function mb_substitute_character(string|int|null $substitute_character = null): string|int|bool { return p\Mbstring::mb_substitute_character($substitute_character); } } if (!function_exists('mb_substr')) { - function mb_substr(string $string, int $start, int $length = null, string $encoding = null): string { return p\Mbstring::mb_substr($string, $start, $length, $encoding); } + function mb_substr(?string $string, ?int $start, ?int $length = null, ?string $encoding = null): string { return p\Mbstring::mb_substr((string) $string, (int) $start, $length, $encoding); } } if (!function_exists('mb_stripos')) { - function mb_stripos(string $haystack, string $needle, int $offset = 0, string $encoding = null): int|false { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); } + function mb_stripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_stripos((string) $haystack, (string) $needle, (int) $offset, $encoding); } } if (!function_exists('mb_stristr')) { - function mb_stristr(string $haystack, string $needle, bool $before_needle = false, string $encoding = null): string|false { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); } + function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } } if (!function_exists('mb_strrchr')) { - function mb_strrchr(string $haystack, string $needle, bool $before_needle = false, string $encoding = null): string|false { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); } + function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrchr((string) $haystack, (string) $needle, $before_needle, (bool) $encoding); } } if (!function_exists('mb_strrichr')) { - function mb_strrichr(string $haystack, string $needle, bool $before_needle = false, string $encoding = null): string|false { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); } + function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } } if (!function_exists('mb_strripos')) { - function mb_strripos(string $haystack, string $needle, int $offset = 0, string $encoding = null): int|false { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); } + function mb_strripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strripos((string) $haystack, (string) $needle, (int) $offset, $encoding); } } if (!function_exists('mb_strrpos')) { - function mb_strrpos(string $haystack, string $needle, int $offset = 0, string $encoding = null): int|false { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); } + function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strrpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } } if (!function_exists('mb_strstr')) { - function mb_strstr(string $haystack, string $needle, bool $before_needle = false, string $encoding = null): string|false { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); } + function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } } if (!function_exists('mb_get_info')) { - function mb_get_info(string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info($type); } + function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); } } if (!function_exists('mb_http_output')) { - function mb_http_output(string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); } + function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); } } if (!function_exists('mb_strwidth')) { - function mb_strwidth(string $string, string $encoding = null): int { return p\Mbstring::mb_strwidth($string, $encoding); } + function mb_strwidth(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strwidth((string) $string, $encoding); } } if (!function_exists('mb_substr_count')) { - function mb_substr_count(string $haystack, string $needle, string $encoding = null): int { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); } + function mb_substr_count(?string $haystack, ?string $needle, ?string $encoding = null): int { return p\Mbstring::mb_substr_count((string) $haystack, (string) $needle, $encoding); } } if (!function_exists('mb_output_handler')) { - function mb_output_handler(string $string, int $status): string { return p\Mbstring::mb_output_handler($string, $status); } + function mb_output_handler(?string $string, ?int $status): string { return p\Mbstring::mb_output_handler((string) $string, (int) $status); } } if (!function_exists('mb_http_input')) { - function mb_http_input(string $type = null): array|string|false { return p\Mbstring::mb_http_input($type); } + function mb_http_input(?string $type = null): array|string|false { return p\Mbstring::mb_http_input($type); } } if (!function_exists('mb_convert_variables')) { - function mb_convert_variables(string $to_encoding, array|string $from_encoding, mixed &$var, mixed &...$vars): string|false { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, $var, ...$vars); } + function mb_convert_variables(?string $to_encoding, array|string|null $from_encoding, mixed &$var, mixed &...$vars): string|false { return p\Mbstring::mb_convert_variables((string) $to_encoding, $from_encoding ?? '', $var, ...$vars); } } if (!function_exists('mb_ord')) { - function mb_ord(string $string, string $encoding = null): int|false { return p\Mbstring::mb_ord($string, $encoding); } + function mb_ord(?string $string, ?string $encoding = null): int|false { return p\Mbstring::mb_ord((string) $string, $encoding); } } if (!function_exists('mb_chr')) { - function mb_chr(int $codepoint, string $encoding = null): string|false { return p\Mbstring::mb_chr($codepoint, $encoding); } + function mb_chr(?int $codepoint, ?string $encoding = null): string|false { return p\Mbstring::mb_chr((int) $codepoint, $encoding); } } if (!function_exists('mb_scrub')) { - function mb_scrub(string $string, string $encoding = null): string { $encoding ??= mb_internal_encoding(); return mb_convert_encoding($string, $encoding, $encoding); } + function mb_scrub(?string $string, ?string $encoding = null): string { $encoding ??= mb_internal_encoding(); return mb_convert_encoding((string) $string, $encoding, $encoding); } } if (!function_exists('mb_str_split')) { - function mb_str_split(string $string, int $length = 1, string $encoding = null): array { return p\Mbstring::mb_str_split($string, $length, $encoding); } + function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null): array { return p\Mbstring::mb_str_split((string) $string, (int) $length, $encoding); } } if (extension_loaded('mbstring')) { diff --git a/vendor/symfony/polyfill-mbstring/composer.json b/vendor/symfony/polyfill-mbstring/composer.json index abdfd3e56..ca8263859 100644 --- a/vendor/symfony/polyfill-mbstring/composer.json +++ b/vendor/symfony/polyfill-mbstring/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" }, @@ -28,7 +28,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", diff --git a/vendor/symfony/polyfill-php72/Php72.php b/vendor/symfony/polyfill-php72/Php72.php index 1e36d5e62..2b706d42b 100644 --- a/vendor/symfony/polyfill-php72/Php72.php +++ b/vendor/symfony/polyfill-php72/Php72.php @@ -73,7 +73,7 @@ final class Php72 return 'Windows'; } - $map = array( + $map = [ 'Darwin' => 'Darwin', 'DragonFly' => 'BSD', 'FreeBSD' => 'BSD', @@ -81,9 +81,9 @@ final class Php72 'OpenBSD' => 'BSD', 'Linux' => 'Linux', 'SunOS' => 'Solaris', - ); + ]; - return isset($map[PHP_OS]) ? $map[PHP_OS] : 'Unknown'; + return isset($map[\PHP_OS]) ? $map[\PHP_OS] : 'Unknown'; } public static function spl_object_id($object) @@ -102,7 +102,7 @@ final class Php72 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); + trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING); return false; } @@ -110,7 +110,7 @@ final class Php72 $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); + trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', \E_USER_WARNING); return false; } @@ -134,7 +134,7 @@ final class Php72 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); + trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING); return false; } @@ -150,12 +150,12 @@ final class Php72 private static function initHashMask() { - $obj = (object) array(); + $obj = (object) []; 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) { + $obFuncs = ['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; diff --git a/vendor/symfony/polyfill-php72/bootstrap.php b/vendor/symfony/polyfill-php72/bootstrap.php index 3154b2c32..b5c92d4c7 100644 --- a/vendor/symfony/polyfill-php72/bootstrap.php +++ b/vendor/symfony/polyfill-php72/bootstrap.php @@ -11,7 +11,7 @@ use Symfony\Polyfill\Php72 as p; -if (PHP_VERSION_ID >= 70200) { +if (\PHP_VERSION_ID >= 70200) { return; } @@ -31,7 +31,7 @@ if (!defined('PHP_OS_FAMILY')) { define('PHP_OS_FAMILY', p\Php72::php_os_family()); } -if ('\\' === DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) { +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')) { diff --git a/vendor/symfony/polyfill-php72/composer.json b/vendor/symfony/polyfill-php72/composer.json index 872b312c1..7946892c3 100644 --- a/vendor/symfony/polyfill-php72/composer.json +++ b/vendor/symfony/polyfill-php72/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php72\\": "" }, @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", diff --git a/vendor/symfony/translation/CHANGELOG.md b/vendor/symfony/translation/CHANGELOG.md index 105a67e26..c80716838 100644 --- a/vendor/symfony/translation/CHANGELOG.md +++ b/vendor/symfony/translation/CHANGELOG.md @@ -1,6 +1,38 @@ CHANGELOG ========= +4.3.0 +----- + + * Improved Xliff 1.2 loader to load the original file's metadata + * Added `TranslatorPathsPass` + +4.2.0 +----- + + * Started using ICU parent locales as fallback locales. + * allow using the ICU message format using domains with the "+intl-icu" suffix + * deprecated `Translator::transChoice()` in favor of using `Translator::trans()` with a `%count%` parameter + * deprecated `TranslatorInterface` in favor of `Symfony\Contracts\Translation\TranslatorInterface` + * deprecated `MessageSelector`, `Interval` and `PluralizationRules`; use `IdentityTranslator` instead + * Added `IntlFormatter` and `IntlFormatterInterface` + * added support for multiple files and directories in `XliffLintCommand` + * Marked `Translator::getFallbackLocales()` and `TranslationDataCollector::getFallbackLocales()` as internal + +4.1.0 +----- + + * The `FileDumper::setBackup()` method is deprecated. + * The `TranslationWriter::disableBackup()` method is deprecated. + * The `XliffFileDumper` will write "name" on the "unit" node when dumping XLIFF 2.0. + +4.0.0 +----- + + * removed the backup feature of the `FileDumper` class + * removed `TranslationWriter::writeTranslations()` method + * removed support for passing `MessageSelector` instances to the constructor of the `Translator` class + 3.4.0 ----- diff --git a/vendor/symfony/translation/Catalogue/AbstractOperation.php b/vendor/symfony/translation/Catalogue/AbstractOperation.php index 4953563db..919bab8ff 100644 --- a/vendor/symfony/translation/Catalogue/AbstractOperation.php +++ b/vendor/symfony/translation/Catalogue/AbstractOperation.php @@ -91,7 +91,7 @@ abstract class AbstractOperation implements OperationInterface public function getMessages($domain) { if (!\in_array($domain, $this->getDomains())) { - throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain)); + throw new InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); } if (!isset($this->messages[$domain]['all'])) { @@ -107,7 +107,7 @@ abstract class AbstractOperation implements OperationInterface public function getNewMessages($domain) { if (!\in_array($domain, $this->getDomains())) { - throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain)); + throw new InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); } if (!isset($this->messages[$domain]['new'])) { @@ -123,7 +123,7 @@ abstract class AbstractOperation implements OperationInterface public function getObsoleteMessages($domain) { if (!\in_array($domain, $this->getDomains())) { - throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain)); + throw new InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); } if (!isset($this->messages[$domain]['obsolete'])) { diff --git a/vendor/symfony/translation/Catalogue/MergeOperation.php b/vendor/symfony/translation/Catalogue/MergeOperation.php index 4e1e3cec3..d2f4abd13 100644 --- a/vendor/symfony/translation/Catalogue/MergeOperation.php +++ b/vendor/symfony/translation/Catalogue/MergeOperation.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Translation\Catalogue; +use Symfony\Component\Translation\MessageCatalogueInterface; + /** * Merge operation between two catalogues as follows: * all = source ∪ target = {x: x ∈ source ∨ x ∈ target} @@ -32,10 +34,11 @@ class MergeOperation extends AbstractOperation 'new' => [], 'obsolete' => [], ]; + $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX; foreach ($this->source->all($domain) as $id => $message) { $this->messages[$domain]['all'][$id] = $message; - $this->result->add([$id => $message], $domain); + $this->result->add([$id => $message], $this->source->defines($id, $intlDomain) ? $intlDomain : $domain); if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) { $this->result->setMetadata($id, $keyMetadata, $domain); } @@ -45,7 +48,7 @@ class MergeOperation extends AbstractOperation if (!$this->source->has($id, $domain)) { $this->messages[$domain]['all'][$id] = $message; $this->messages[$domain]['new'][$id] = $message; - $this->result->add([$id => $message], $domain); + $this->result->add([$id => $message], $this->target->defines($id, $intlDomain) ? $intlDomain : $domain); if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) { $this->result->setMetadata($id, $keyMetadata, $domain); } diff --git a/vendor/symfony/translation/Catalogue/TargetOperation.php b/vendor/symfony/translation/Catalogue/TargetOperation.php index 35eff71ff..22aa9a391 100644 --- a/vendor/symfony/translation/Catalogue/TargetOperation.php +++ b/vendor/symfony/translation/Catalogue/TargetOperation.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Translation\Catalogue; +use Symfony\Component\Translation\MessageCatalogueInterface; + /** * Target operation between two catalogues: * intersection = source ∩ target = {x: x ∈ source ∧ x ∈ target} @@ -33,6 +35,7 @@ class TargetOperation extends AbstractOperation 'new' => [], 'obsolete' => [], ]; + $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX; // For 'all' messages, the code can't be simplified as ``$this->messages[$domain]['all'] = $target->all($domain);``, // because doing so will drop messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback} @@ -46,7 +49,7 @@ class TargetOperation extends AbstractOperation foreach ($this->source->all($domain) as $id => $message) { if ($this->target->has($id, $domain)) { $this->messages[$domain]['all'][$id] = $message; - $this->result->add([$id => $message], $domain); + $this->result->add([$id => $message], $this->target->defines($id, $intlDomain) ? $intlDomain : $domain); if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) { $this->result->setMetadata($id, $keyMetadata, $domain); } @@ -59,7 +62,7 @@ class TargetOperation extends AbstractOperation if (!$this->source->has($id, $domain)) { $this->messages[$domain]['all'][$id] = $message; $this->messages[$domain]['new'][$id] = $message; - $this->result->add([$id => $message], $domain); + $this->result->add([$id => $message], $this->target->defines($id, $intlDomain) ? $intlDomain : $domain); if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) { $this->result->setMetadata($id, $keyMetadata, $domain); } diff --git a/vendor/symfony/translation/Command/XliffLintCommand.php b/vendor/symfony/translation/Command/XliffLintCommand.php index 65d5a0e54..87cb91201 100644 --- a/vendor/symfony/translation/Command/XliffLintCommand.php +++ b/vendor/symfony/translation/Command/XliffLintCommand.php @@ -13,11 +13,12 @@ namespace Symfony\Component\Translation\Command; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Exception\RuntimeException; +use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Translation\Exception\InvalidArgumentException; +use Symfony\Component\Translation\Util\XliffUtils; /** * Validates XLIFF files syntax and outputs encountered errors. @@ -34,13 +35,15 @@ class XliffLintCommand extends Command private $displayCorrectFiles; private $directoryIteratorProvider; private $isReadableProvider; + private $requireStrictFileNames; - public function __construct($name = null, $directoryIteratorProvider = null, $isReadableProvider = null) + public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null, bool $requireStrictFileNames = true) { parent::__construct($name); $this->directoryIteratorProvider = $directoryIteratorProvider; $this->isReadableProvider = $isReadableProvider; + $this->requireStrictFileNames = $requireStrictFileNames; } /** @@ -50,7 +53,7 @@ class XliffLintCommand extends Command { $this ->setDescription('Lints a XLIFF file and outputs encountered errors') - ->addArgument('filename', null, 'A file or a directory or STDIN') + ->addArgument('filename', InputArgument::IS_ARRAY, 'A file or a directory or STDIN') ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt') ->setHelp(<<%command.name% command lints a XLIFF file and outputs to STDOUT @@ -77,11 +80,11 @@ EOF protected function execute(InputInterface $input, OutputInterface $output) { $io = new SymfonyStyle($input, $output); - $filename = $input->getArgument('filename'); + $filenames = (array) $input->getArgument('filename'); $this->format = $input->getOption('format'); $this->displayCorrectFiles = $output->isVerbose(); - if (!$filename) { + if (0 === \count($filenames)) { if (!$stdin = $this->getStdin()) { throw new RuntimeException('Please provide a filename or pipe file content to STDIN.'); } @@ -89,13 +92,15 @@ EOF return $this->display($io, [$this->validate($stdin)]); } - if (!$this->isReadable($filename)) { - throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename)); - } - $filesInfo = []; - foreach ($this->getFiles($filename) as $file) { - $filesInfo[] = $this->validate(file_get_contents($file), $file); + foreach ($filenames as $filename) { + if (!$this->isReadable($filename)) { + throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename)); + } + + foreach ($this->getFiles($filename) as $file) { + $filesInfo[] = $this->validate(file_get_contents($file), $file); + } } return $this->display($io, $filesInfo); @@ -103,31 +108,47 @@ EOF private function validate($content, $file = null) { + $errors = []; + // Avoid: Warning DOMDocument::loadXML(): Empty string supplied as input if ('' === trim($content)) { return ['file' => $file, 'valid' => true]; } - libxml_use_internal_errors(true); + $internal = libxml_use_internal_errors(true); $document = new \DOMDocument(); $document->loadXML($content); - if ($document->schemaValidate(__DIR__.'/../Resources/schemas/xliff-core-1.2-strict.xsd')) { - return ['file' => $file, 'valid' => true]; + + if (null !== $targetLanguage = $this->getTargetLanguageFromFile($document)) { + $normalizedLocale = preg_quote(str_replace('-', '_', $targetLanguage), '/'); + // strict file names require translation files to be named '____.locale.xlf' + // otherwise, both '____.locale.xlf' and 'locale.____.xlf' are allowed + // also, the regexp matching must be case-insensitive, as defined for 'target-language' values + // http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#target-language + $expectedFilenamePattern = $this->requireStrictFileNames ? sprintf('/^.*\.(?i:%s)\.xlf/', $normalizedLocale) : sprintf('/^(.*\.(?i:%s)\.xlf|(?i:%s)\..*\.xlf)/', $normalizedLocale, $normalizedLocale); + + if (0 === preg_match($expectedFilenamePattern, basename($file))) { + $errors[] = [ + 'line' => -1, + 'column' => -1, + 'message' => sprintf('There is a mismatch between the language included in the file name ("%s") and the "%s" value used in the "target-language" attribute of the file.', basename($file), $targetLanguage), + ]; + } } - $errorMessages = array_map(function ($error) { - return [ - 'line' => $error->line, - 'column' => $error->column, - 'message' => trim($error->message), + foreach (XliffUtils::validateSchema($document) as $xmlError) { + $errors[] = [ + 'line' => $xmlError['line'], + 'column' => $xmlError['column'], + 'message' => $xmlError['message'], ]; - }, libxml_get_errors()); + } libxml_clear_errors(); - libxml_use_internal_errors(false); + libxml_use_internal_errors($internal); - return ['file' => $file, 'valid' => false, 'messages' => $errorMessages]; + return ['file' => $file, 'valid' => 0 === \count($errors), 'messages' => $errors]; } private function display(SymfonyStyle $io, array $files) @@ -180,7 +201,7 @@ EOF } }); - $io->writeln(json_encode($filesInfo, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)); + $io->writeln(json_encode($filesInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); return min($errors, 1); } @@ -207,13 +228,13 @@ EOF */ private function getStdin() { - if (0 !== ftell(\STDIN)) { + if (0 !== ftell(STDIN)) { return null; } $inputs = ''; - while (!feof(\STDIN)) { - $inputs .= fread(\STDIN, 1024); + while (!feof(STDIN)) { + $inputs .= fread(STDIN, 1024); } return $inputs; @@ -229,7 +250,7 @@ EOF }; if (null !== $this->directoryIteratorProvider) { - return \call_user_func($this->directoryIteratorProvider, $directory, $default); + return ($this->directoryIteratorProvider)($directory, $default); } return $default($directory); @@ -242,9 +263,20 @@ EOF }; if (null !== $this->isReadableProvider) { - return \call_user_func($this->isReadableProvider, $fileOrDirectory, $default); + return ($this->isReadableProvider)($fileOrDirectory, $default); } return $default($fileOrDirectory); } + + private function getTargetLanguageFromFile(\DOMDocument $xliffContents): ?string + { + foreach ($xliffContents->getElementsByTagName('file')[0]->attributes ?? [] as $attribute) { + if ('target-language' === $attribute->nodeName) { + return $attribute->nodeValue; + } + } + + return null; + } } diff --git a/vendor/symfony/translation/DataCollector/TranslationDataCollector.php b/vendor/symfony/translation/DataCollector/TranslationDataCollector.php index 5b96a22f3..222ff9ea4 100644 --- a/vendor/symfony/translation/DataCollector/TranslationDataCollector.php +++ b/vendor/symfony/translation/DataCollector/TranslationDataCollector.php @@ -37,12 +37,9 @@ class TranslationDataCollector extends DataCollector implements LateDataCollecto { $messages = $this->sanitizeCollectedMessages($this->translator->getCollectedMessages()); - $this->data = $this->computeCount($messages); + $this->data += $this->computeCount($messages); $this->data['messages'] = $messages; - $this->data['locale'] = $this->translator->getLocale(); - $this->data['fallback_locales'] = $this->translator->getFallbackLocales(); - $this->data = $this->cloneVar($this->data); } @@ -51,6 +48,8 @@ class TranslationDataCollector extends DataCollector implements LateDataCollecto */ public function collect(Request $request, Response $response, \Exception $exception = null) { + $this->data['locale'] = $this->translator->getLocale(); + $this->data['fallback_locales'] = $this->translator->getFallbackLocales(); } /** @@ -98,6 +97,9 @@ class TranslationDataCollector extends DataCollector implements LateDataCollecto return !empty($this->data['locale']) ? $this->data['locale'] : null; } + /** + * @internal since Symfony 4.2 + */ public function getFallbackLocales() { return (isset($this->data['fallback_locales']) && \count($this->data['fallback_locales']) > 0) ? $this->data['fallback_locales'] : []; diff --git a/vendor/symfony/translation/DataCollectorTranslator.php b/vendor/symfony/translation/DataCollectorTranslator.php index e70e5f5e1..7ef41839a 100644 --- a/vendor/symfony/translation/DataCollectorTranslator.php +++ b/vendor/symfony/translation/DataCollectorTranslator.php @@ -13,11 +13,14 @@ namespace Symfony\Component\Translation; use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface; use Symfony\Component\Translation\Exception\InvalidArgumentException; +use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; +use Symfony\Contracts\Translation\LocaleAwareInterface; +use Symfony\Contracts\Translation\TranslatorInterface; /** * @author Abdellatif Ait boudad */ -class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInterface, WarmableInterface +class DataCollectorTranslator implements LegacyTranslatorInterface, TranslatorInterface, TranslatorBagInterface, WarmableInterface { const MESSAGE_DEFINED = 0; const MESSAGE_MISSING = 1; @@ -33,10 +36,13 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter /** * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface */ - public function __construct(TranslatorInterface $translator) + public function __construct($translator) { - if (!$translator instanceof TranslatorBagInterface) { - throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', \get_class($translator))); + if (!$translator instanceof LegacyTranslatorInterface && !$translator instanceof TranslatorInterface) { + throw new \TypeError(sprintf('Argument 1 passed to %s() must be an instance of %s, %s given.', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator))); + } + if (!$translator instanceof TranslatorBagInterface || !$translator instanceof LocaleAwareInterface) { + throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface, TranslatorBagInterface and LocaleAwareInterface.', \get_class($translator))); } $this->translator = $translator; @@ -55,11 +61,18 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2, use the trans() method instead with a %count% parameter */ public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null) { - $trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale); - $this->collectMessage($locale, $domain, $id, $trans, $parameters, $number); + if ($this->translator instanceof TranslatorInterface) { + $trans = $this->translator->trans($id, ['%count%' => $number] + $parameters, $domain, $locale); + } else { + $trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale); + } + + $this->collectMessage($locale, $domain, $id, $trans, ['%count%' => $number] + $parameters); return $trans; } @@ -117,7 +130,7 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter */ public function __call($method, $args) { - return \call_user_func_array([$this->translator, $method], $args); + return $this->translator->{$method}(...$args); } /** @@ -134,9 +147,8 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter * @param string $id * @param string $translation * @param array|null $parameters - * @param int|null $number */ - private function collectMessage($locale, $domain, $id, $translation, $parameters = [], $number = null) + private function collectMessage($locale, $domain, $id, $translation, $parameters = []) { if (null === $domain) { $domain = 'messages'; @@ -170,8 +182,8 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter 'id' => $id, 'translation' => $translation, 'parameters' => $parameters, - 'transChoiceNumber' => $number, 'state' => $state, + 'transChoiceNumber' => isset($parameters['%count%']) && is_numeric($parameters['%count%']) ? $parameters['%count%'] : null, ]; } } diff --git a/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php b/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php index 4656d667a..930f36d72 100644 --- a/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php +++ b/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php @@ -23,7 +23,7 @@ class TranslationDumperPass implements CompilerPassInterface private $writerServiceId; private $dumperTag; - public function __construct($writerServiceId = 'translation.writer', $dumperTag = 'translation.dumper') + public function __construct(string $writerServiceId = 'translation.writer', string $dumperTag = 'translation.dumper') { $this->writerServiceId = $writerServiceId; $this->dumperTag = $dumperTag; diff --git a/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php b/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php index bb4c5dca7..d08b2ba5f 100644 --- a/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php +++ b/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php @@ -24,7 +24,7 @@ class TranslationExtractorPass implements CompilerPassInterface private $extractorServiceId; private $extractorTag; - public function __construct($extractorServiceId = 'translation.extractor', $extractorTag = 'translation.extractor') + public function __construct(string $extractorServiceId = 'translation.extractor', string $extractorTag = 'translation.extractor') { $this->extractorServiceId = $extractorServiceId; $this->extractorTag = $extractorTag; diff --git a/vendor/symfony/translation/DependencyInjection/TranslatorPass.php b/vendor/symfony/translation/DependencyInjection/TranslatorPass.php index 5cad19ce5..ed4a840d8 100644 --- a/vendor/symfony/translation/DependencyInjection/TranslatorPass.php +++ b/vendor/symfony/translation/DependencyInjection/TranslatorPass.php @@ -24,12 +24,8 @@ class TranslatorPass implements CompilerPassInterface private $debugCommandServiceId; private $updateCommandServiceId; - public function __construct($translatorServiceId = 'translator.default', $readerServiceId = 'translation.loader', $loaderTag = 'translation.loader', $debugCommandServiceId = 'console.command.translation_debug', $updateCommandServiceId = 'console.command.translation_update') + public function __construct(string $translatorServiceId = 'translator.default', string $readerServiceId = 'translation.reader', string $loaderTag = 'translation.loader', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update') { - if ('translation.loader' === $readerServiceId && 2 > \func_num_args()) { - @trigger_error(sprintf('The default value for $readerServiceId in "%s()" will change in 4.0 to "translation.reader".', __METHOD__), \E_USER_DEPRECATED); - } - $this->translatorServiceId = $translatorServiceId; $this->readerServiceId = $readerServiceId; $this->loaderTag = $loaderTag; @@ -62,18 +58,6 @@ class TranslatorPass implements CompilerPassInterface } } - // Duplicated code to support "translation.reader", to be removed in 4.0 - if ('translation.reader' !== $this->readerServiceId) { - if ($container->hasDefinition('translation.reader')) { - $definition = $container->getDefinition('translation.reader'); - foreach ($loaders as $id => $formats) { - foreach ($formats as $format) { - $definition->addMethodCall('addLoader', [$format, $loaderRefs[$id]]); - } - } - } - } - $container ->findDefinition($this->translatorServiceId) ->replaceArgument(0, ServiceLocatorTagPass::register($container, $loaderRefs)) @@ -84,12 +68,22 @@ class TranslatorPass implements CompilerPassInterface return; } + $paths = array_keys($container->getDefinition('twig.template_iterator')->getArgument(2)); if ($container->hasDefinition($this->debugCommandServiceId)) { - $container->getDefinition($this->debugCommandServiceId)->replaceArgument(4, $container->getParameter('twig.default_path')); - } + $definition = $container->getDefinition($this->debugCommandServiceId); + $definition->replaceArgument(4, $container->getParameter('twig.default_path')); + if (\count($definition->getArguments()) > 6) { + $definition->replaceArgument(6, $paths); + } + } if ($container->hasDefinition($this->updateCommandServiceId)) { - $container->getDefinition($this->updateCommandServiceId)->replaceArgument(5, $container->getParameter('twig.default_path')); + $definition = $container->getDefinition($this->updateCommandServiceId); + $definition->replaceArgument(5, $container->getParameter('twig.default_path')); + + if (\count($definition->getArguments()) > 7) { + $definition->replaceArgument(7, $paths); + } } } } diff --git a/vendor/symfony/translation/DependencyInjection/TranslatorPathsPass.php b/vendor/symfony/translation/DependencyInjection/TranslatorPathsPass.php index a91aef617..8ff2587dd 100644 --- a/vendor/symfony/translation/DependencyInjection/TranslatorPathsPass.php +++ b/vendor/symfony/translation/DependencyInjection/TranslatorPathsPass.php @@ -48,7 +48,7 @@ class TranslatorPathsPass extends AbstractRecursivePass foreach ($this->findControllerArguments($container) as $controller => $argument) { $id = substr($controller, 0, strpos($controller, ':') ?: \strlen($controller)); if ($container->hasDefinition($id)) { - [$locatorRef] = $argument->getValues(); + list($locatorRef) = $argument->getValues(); $this->controllers[(string) $locatorRef][$container->getDefinition($id)->getClass()] = true; } } diff --git a/vendor/symfony/translation/Dumper/FileDumper.php b/vendor/symfony/translation/Dumper/FileDumper.php index eebb932e0..2009c5340 100644 --- a/vendor/symfony/translation/Dumper/FileDumper.php +++ b/vendor/symfony/translation/Dumper/FileDumper.php @@ -17,7 +17,6 @@ use Symfony\Component\Translation\MessageCatalogue; /** * FileDumper is an implementation of DumperInterface that dump a message catalogue to file(s). - * Performs backup of already existing files. * * Options: * - path (mandatory): the directory where the files should be saved @@ -33,13 +32,6 @@ abstract class FileDumper implements DumperInterface */ protected $relativePathTemplate = '%domain%.%locale%.%extension%'; - /** - * Make file backup before the dump. - * - * @var bool - */ - private $backup = true; - /** * Sets the template for the relative paths to files. * @@ -54,10 +46,16 @@ abstract class FileDumper implements DumperInterface * Sets backup flag. * * @param bool $backup + * + * @deprecated since Symfony 4.1 */ public function setBackup($backup) { - $this->backup = $backup; + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1.', __METHOD__), E_USER_DEPRECATED); + + if (false !== $backup) { + throw new \LogicException('The backup feature is no longer supported.'); + } } /** @@ -71,20 +69,33 @@ abstract class FileDumper implements DumperInterface // save a file for each domain foreach ($messages->getDomains() as $domain) { - // backup $fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale()); - if (file_exists($fullpath)) { - if ($this->backup) { - @trigger_error('Creating a backup while dumping a message catalogue is deprecated since Symfony 3.1 and will be removed in 4.0. Use TranslationWriter::disableBackup() to disable the backup.', \E_USER_DEPRECATED); - copy($fullpath, $fullpath.'~'); - } - } else { + if (!file_exists($fullpath)) { $directory = \dirname($fullpath); if (!file_exists($directory) && !@mkdir($directory, 0777, true)) { throw new RuntimeException(sprintf('Unable to create directory "%s".', $directory)); } } - // save file + + $intlDomain = $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX; + $intlMessages = $messages->all($intlDomain); + + if ($intlMessages) { + $intlPath = $options['path'].'/'.$this->getRelativePath($intlDomain, $messages->getLocale()); + file_put_contents($intlPath, $this->formatCatalogue($messages, $intlDomain, $options)); + + $messages->replace([], $intlDomain); + + try { + if ($messages->all($domain)) { + file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options)); + } + continue; + } finally { + $messages->replace($intlMessages, $intlDomain); + } + } + file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options)); } } @@ -107,13 +118,8 @@ abstract class FileDumper implements DumperInterface /** * Gets the relative file path using the template. - * - * @param string $domain The domain - * @param string $locale The locale - * - * @return string The relative file path */ - private function getRelativePath($domain, $locale) + private function getRelativePath(string $domain, string $locale): string { return strtr($this->relativePathTemplate, [ '%domain%' => $domain, diff --git a/vendor/symfony/translation/Dumper/JsonFileDumper.php b/vendor/symfony/translation/Dumper/JsonFileDumper.php index 78e10f26e..2af8231bd 100644 --- a/vendor/symfony/translation/Dumper/JsonFileDumper.php +++ b/vendor/symfony/translation/Dumper/JsonFileDumper.php @@ -25,11 +25,7 @@ class JsonFileDumper extends FileDumper */ public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = []) { - if (isset($options['json_encoding'])) { - $flags = $options['json_encoding']; - } else { - $flags = \JSON_PRETTY_PRINT; - } + $flags = $options['json_encoding'] ?? JSON_PRETTY_PRINT; return json_encode($messages->all($domain), $flags); } diff --git a/vendor/symfony/translation/Dumper/PoFileDumper.php b/vendor/symfony/translation/Dumper/PoFileDumper.php index 0f7e6fa83..5f6008628 100644 --- a/vendor/symfony/translation/Dumper/PoFileDumper.php +++ b/vendor/symfony/translation/Dumper/PoFileDumper.php @@ -39,6 +39,18 @@ class PoFileDumper extends FileDumper } else { $newLine = true; } + $metadata = $messages->getMetadata($source, $domain); + + if (isset($metadata['comments'])) { + $output .= $this->formatComments($metadata['comments']); + } + if (isset($metadata['flags'])) { + $output .= $this->formatComments(implode(',', (array) $metadata['flags']), ','); + } + if (isset($metadata['sources'])) { + $output .= $this->formatComments(implode(' ', (array) $metadata['sources']), ':'); + } + $output .= sprintf('msgid "%s"'."\n", $this->escape($source)); $output .= sprintf('msgstr "%s"'."\n", $this->escape($target)); } @@ -58,4 +70,15 @@ class PoFileDumper extends FileDumper { return addcslashes($str, "\0..\37\42\134"); } + + private function formatComments($comments, string $prefix = ''): ?string + { + $output = null; + + foreach ((array) $comments as $comment) { + $output .= sprintf('#%s %s'."\n", $prefix, $comment); + } + + return $output; + } } diff --git a/vendor/symfony/translation/Dumper/QtFileDumper.php b/vendor/symfony/translation/Dumper/QtFileDumper.php index ec93f92e4..79a64b243 100644 --- a/vendor/symfony/translation/Dumper/QtFileDumper.php +++ b/vendor/symfony/translation/Dumper/QtFileDumper.php @@ -33,6 +33,17 @@ class QtFileDumper extends FileDumper foreach ($messages->all($domain) as $source => $target) { $message = $context->appendChild($dom->createElement('message')); + $metadata = $messages->getMetadata($source, $domain); + if (isset($metadata['sources'])) { + foreach ((array) $metadata['sources'] as $location) { + $loc = explode(':', $location, 2); + $location = $message->appendChild($dom->createElement('location')); + $location->setAttribute('filename', $loc[0]); + if (isset($loc[1])) { + $location->setAttribute('line', $loc[1]); + } + } + } $message->appendChild($dom->createElement('source', $source)); $message->appendChild($dom->createElement('translation', $target)); } diff --git a/vendor/symfony/translation/Dumper/XliffFileDumper.php b/vendor/symfony/translation/Dumper/XliffFileDumper.php index f933be8b2..7855f7165 100644 --- a/vendor/symfony/translation/Dumper/XliffFileDumper.php +++ b/vendor/symfony/translation/Dumper/XliffFileDumper.php @@ -141,11 +141,20 @@ class XliffFileDumper extends FileDumper $xliff->setAttribute('trgLang', str_replace('_', '-', $messages->getLocale())); $xliffFile = $xliff->appendChild($dom->createElement('file')); - $xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale()); + if (MessageCatalogue::INTL_DOMAIN_SUFFIX === substr($domain, -($suffixLength = \strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX)))) { + $xliffFile->setAttribute('id', substr($domain, 0, -$suffixLength).'.'.$messages->getLocale()); + } else { + $xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale()); + } foreach ($messages->all($domain) as $source => $target) { $translation = $dom->createElement('unit'); $translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._')); + $name = $source; + if (\strlen($source) > 80) { + $name = substr(md5($source), -7); + } + $translation->setAttribute('name', $name); $metadata = $messages->getMetadata($source, $domain); // Add notes section diff --git a/vendor/symfony/translation/Dumper/YamlFileDumper.php b/vendor/symfony/translation/Dumper/YamlFileDumper.php index f7e1bcb80..d6e4af8fb 100644 --- a/vendor/symfony/translation/Dumper/YamlFileDumper.php +++ b/vendor/symfony/translation/Dumper/YamlFileDumper.php @@ -25,7 +25,7 @@ class YamlFileDumper extends FileDumper { private $extension; - public function __construct(/**string */$extension = 'yml') + public function __construct(string $extension = 'yml') { $this->extension = $extension; } diff --git a/vendor/symfony/translation/Exception/ExceptionInterface.php b/vendor/symfony/translation/Exception/ExceptionInterface.php index c85fb93ca..8f9c54ef7 100644 --- a/vendor/symfony/translation/Exception/ExceptionInterface.php +++ b/vendor/symfony/translation/Exception/ExceptionInterface.php @@ -16,6 +16,6 @@ namespace Symfony\Component\Translation\Exception; * * @author Fabien Potencier */ -interface ExceptionInterface +interface ExceptionInterface extends \Throwable { } diff --git a/vendor/symfony/translation/Extractor/AbstractFileExtractor.php b/vendor/symfony/translation/Extractor/AbstractFileExtractor.php index 2da1fff6e..618df7324 100644 --- a/vendor/symfony/translation/Extractor/AbstractFileExtractor.php +++ b/vendor/symfony/translation/Extractor/AbstractFileExtractor.php @@ -27,7 +27,7 @@ abstract class AbstractFileExtractor */ protected function extractFiles($resource) { - if (\is_array($resource) || $resource instanceof \Traversable) { + if (is_iterable($resource)) { $files = []; foreach ($resource as $file) { if ($this->canBeExtracted($file)) { @@ -43,14 +43,9 @@ abstract class AbstractFileExtractor return $files; } - /** - * @param string $file - * - * @return \SplFileInfo - */ - private function toSplFileInfo($file) + private function toSplFileInfo(string $file): \SplFileInfo { - return ($file instanceof \SplFileInfo) ? $file : new \SplFileInfo($file); + return new \SplFileInfo($file); } /** diff --git a/vendor/symfony/translation/Extractor/PhpExtractor.php b/vendor/symfony/translation/Extractor/PhpExtractor.php index e46bedbd8..265b8d768 100644 --- a/vendor/symfony/translation/Extractor/PhpExtractor.php +++ b/vendor/symfony/translation/Extractor/PhpExtractor.php @@ -81,12 +81,9 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface { $files = $this->extractFiles($resource); foreach ($files as $file) { - $this->parseTokens(token_get_all(file_get_contents($file)), $catalog); + $this->parseTokens(token_get_all(file_get_contents($file)), $catalog, $file); - if (\PHP_VERSION_ID >= 70000) { - // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 - gc_mem_caches(); - } + gc_mem_caches(); } } @@ -121,7 +118,7 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface { for (; $tokenIterator->valid(); $tokenIterator->next()) { $t = $tokenIterator->current(); - if (\T_WHITESPACE !== $t[0]) { + if (T_WHITESPACE !== $t[0]) { break; } } @@ -169,23 +166,23 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface } switch ($t[0]) { - case \T_START_HEREDOC: + case T_START_HEREDOC: $docToken = $t[1]; break; - case \T_ENCAPSED_AND_WHITESPACE: - case \T_CONSTANT_ENCAPSED_STRING: + case T_ENCAPSED_AND_WHITESPACE: + case T_CONSTANT_ENCAPSED_STRING: if ('' === $docToken) { $message .= PhpStringTokenParser::parse($t[1]); } else { $docPart = $t[1]; } break; - case \T_END_HEREDOC: + case T_END_HEREDOC: $message .= PhpStringTokenParser::parseDocString($docToken, $docPart); $docToken = ''; $docPart = ''; break; - case \T_WHITESPACE: + case T_WHITESPACE: break; default: break 2; @@ -198,10 +195,16 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface /** * Extracts trans message from PHP tokens. * - * @param array $tokens + * @param array $tokens + * @param string $filename */ - protected function parseTokens($tokens, MessageCatalogue $catalog) + protected function parseTokens($tokens, MessageCatalogue $catalog/*, string $filename*/) { + if (\func_num_args() < 3 && __CLASS__ !== \get_class($this) && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) { + @trigger_error(sprintf('The "%s()" method will have a new "string $filename" argument in version 5.0, not defining it is deprecated since Symfony 4.3.', __METHOD__), E_USER_DEPRECATED); + } + $filename = 2 < \func_num_args() ? func_get_arg(2) : ''; + $tokenIterator = new \ArrayIterator($tokens); for ($key = 0; $key < $tokenIterator->count(); ++$key) { @@ -238,6 +241,10 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface if ($message) { $catalog->set($message, $this->prefix.$message, $domain); + $metadata = $catalog->getMetadata($message, $domain) ?? []; + $normalizedFilename = preg_replace('{[\\\\/]+}', '/', $filename); + $metadata['sources'][] = $normalizedFilename.':'.$tokens[$key][2]; + $catalog->setMetadata($message, $metadata, $domain); break; } } @@ -253,7 +260,7 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface */ protected function canBeExtracted($file) { - return $this->isFile($file) && 'php' === pathinfo($file, \PATHINFO_EXTENSION); + return $this->isFile($file) && 'php' === pathinfo($file, PATHINFO_EXTENSION); } /** diff --git a/vendor/symfony/translation/Formatter/ChoiceMessageFormatterInterface.php b/vendor/symfony/translation/Formatter/ChoiceMessageFormatterInterface.php index 027b2eb5b..621dbb292 100644 --- a/vendor/symfony/translation/Formatter/ChoiceMessageFormatterInterface.php +++ b/vendor/symfony/translation/Formatter/ChoiceMessageFormatterInterface.php @@ -13,6 +13,8 @@ namespace Symfony\Component\Translation\Formatter; /** * @author Abdellatif Ait boudad + * + * @deprecated since Symfony 4.2, use MessageFormatterInterface::format() with a %count% parameter instead */ interface ChoiceMessageFormatterInterface { diff --git a/vendor/symfony/translation/Formatter/IntlFormatter.php b/vendor/symfony/translation/Formatter/IntlFormatter.php index f7f1c36a2..ad4a45b95 100644 --- a/vendor/symfony/translation/Formatter/IntlFormatter.php +++ b/vendor/symfony/translation/Formatter/IntlFormatter.php @@ -40,7 +40,7 @@ class IntlFormatter implements IntlFormatterInterface try { $this->cache[$locale][$message] = $formatter = new \MessageFormatter($locale, $message); } catch (\IntlException $e) { - throw new InvalidArgumentException(sprintf('Invalid message format (error #%d): ', intl_get_error_code()).intl_get_error_message(), 0, $e); + throw new InvalidArgumentException(sprintf('Invalid message format (error #%d): %s.', intl_get_error_code(), intl_get_error_message()), 0, $e); } } @@ -52,7 +52,7 @@ class IntlFormatter implements IntlFormatterInterface } if (false === $message = $formatter->format($parameters)) { - throw new InvalidArgumentException(sprintf('Unable to format message (error #%s): ', $formatter->getErrorCode()).$formatter->getErrorMessage()); + throw new InvalidArgumentException(sprintf('Unable to format message (error #%s): %s.', $formatter->getErrorCode(), $formatter->getErrorMessage())); } return $message; diff --git a/vendor/symfony/translation/Formatter/MessageFormatter.php b/vendor/symfony/translation/Formatter/MessageFormatter.php index f7204c3b0..030d7a5c3 100644 --- a/vendor/symfony/translation/Formatter/MessageFormatter.php +++ b/vendor/symfony/translation/Formatter/MessageFormatter.php @@ -11,21 +11,32 @@ namespace Symfony\Component\Translation\Formatter; +use Symfony\Component\Translation\IdentityTranslator; use Symfony\Component\Translation\MessageSelector; +use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; /** * @author Abdellatif Ait boudad */ -class MessageFormatter implements MessageFormatterInterface, ChoiceMessageFormatterInterface +class MessageFormatter implements MessageFormatterInterface, IntlFormatterInterface, ChoiceMessageFormatterInterface { - private $selector; + private $translator; + private $intlFormatter; /** - * @param MessageSelector|null $selector The message selector for pluralization + * @param TranslatorInterface|null $translator An identity translator to use as selector for pluralization */ - public function __construct(MessageSelector $selector = null) + public function __construct($translator = null, IntlFormatterInterface $intlFormatter = null) { - $this->selector = $selector ?: new MessageSelector(); + if ($translator instanceof MessageSelector) { + $translator = new IdentityTranslator($translator); + } elseif (null !== $translator && !$translator instanceof TranslatorInterface && !$translator instanceof LegacyTranslatorInterface) { + throw new \TypeError(sprintf('Argument 1 passed to %s() must be an instance of %s, %s given.', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator))); + } + + $this->translator = $translator ?? new IdentityTranslator(); + $this->intlFormatter = $intlFormatter ?? new IntlFormatter(); } /** @@ -33,16 +44,36 @@ class MessageFormatter implements MessageFormatterInterface, ChoiceMessageFormat */ public function format($message, $locale, array $parameters = []) { + if ($this->translator instanceof TranslatorInterface) { + return $this->translator->trans($message, $parameters, null, $locale); + } + return strtr($message, $parameters); } /** * {@inheritdoc} */ + public function formatIntl(string $message, string $locale, array $parameters = []): string + { + return $this->intlFormatter->formatIntl($message, $locale, $parameters); + } + + /** + * {@inheritdoc} + * + * @deprecated since Symfony 4.2, use format() with a %count% parameter instead + */ public function choiceFormat($message, $number, $locale, array $parameters = []) { - $parameters = array_merge(['%count%' => $number], $parameters); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the format() one instead with a %%count%% parameter.', __METHOD__), E_USER_DEPRECATED); - return $this->format($this->selector->choose($message, (int) $number, $locale), $locale, $parameters); + $parameters = ['%count%' => $number] + $parameters; + + if ($this->translator instanceof TranslatorInterface) { + return $this->format($message, $locale, $parameters); + } + + return $this->format($this->translator->transChoice($message, $number, [], null, $locale), $locale, $parameters); } } diff --git a/vendor/symfony/translation/IdentityTranslator.php b/vendor/symfony/translation/IdentityTranslator.php index 2d90509d8..b15792a9b 100644 --- a/vendor/symfony/translation/IdentityTranslator.php +++ b/vendor/symfony/translation/IdentityTranslator.php @@ -11,53 +11,51 @@ namespace Symfony\Component\Translation; +use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; +use Symfony\Contracts\Translation\TranslatorTrait; + /** * IdentityTranslator does not translate anything. * * @author Fabien Potencier */ -class IdentityTranslator implements TranslatorInterface +class IdentityTranslator implements LegacyTranslatorInterface, TranslatorInterface { + use TranslatorTrait; + private $selector; - private $locale; /** * @param MessageSelector|null $selector The message selector for pluralization */ public function __construct(MessageSelector $selector = null) { - $this->selector = $selector ?: new MessageSelector(); - } - - /** - * {@inheritdoc} - */ - public function setLocale($locale) - { - $this->locale = $locale; - } - - /** - * {@inheritdoc} - */ - public function getLocale() - { - return $this->locale ?: \Locale::getDefault(); - } - - /** - * {@inheritdoc} - */ - public function trans($id, array $parameters = [], $domain = null, $locale = null) - { - return strtr((string) $id, $parameters); + $this->selector = $selector; + + if (__CLASS__ !== \get_class($this)) { + @trigger_error(sprintf('Calling "%s()" is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); + } } /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2, use the trans() method instead with a %count% parameter */ public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null) { - return strtr($this->selector->choose((string) $id, (int) $number, $locale ?: $this->getLocale()), $parameters); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the trans() one instead with a "%%count%%" parameter.', __METHOD__), E_USER_DEPRECATED); + + if ($this->selector) { + return strtr($this->selector->choose((string) $id, $number, $locale ?: $this->getLocale()), $parameters); + } + + return $this->trans($id, ['%count%' => $number] + $parameters, $domain, $locale); + } + + private function getPluralizationRule(int $number, string $locale): int + { + return PluralizationRules::get($number, $locale, false); } } diff --git a/vendor/symfony/translation/Interval.php b/vendor/symfony/translation/Interval.php index 9e2cae648..a0e484da8 100644 --- a/vendor/symfony/translation/Interval.php +++ b/vendor/symfony/translation/Interval.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Translation; +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.2, use IdentityTranslator instead.', Interval::class), E_USER_DEPRECATED); + use Symfony\Component\Translation\Exception\InvalidArgumentException; /** @@ -32,6 +34,7 @@ use Symfony\Component\Translation\Exception\InvalidArgumentException; * @author Fabien Potencier * * @see http://en.wikipedia.org/wiki/Interval_%28mathematics%29#The_ISO_notation + * @deprecated since Symfony 4.2, use IdentityTranslator instead */ class Interval { diff --git a/vendor/symfony/translation/Loader/IcuDatFileLoader.php b/vendor/symfony/translation/Loader/IcuDatFileLoader.php index 7d15aecb6..7bbf4c200 100644 --- a/vendor/symfony/translation/Loader/IcuDatFileLoader.php +++ b/vendor/symfony/translation/Loader/IcuDatFileLoader.php @@ -39,12 +39,11 @@ class IcuDatFileLoader extends IcuResFileLoader try { $rb = new \ResourceBundle($locale, $resource); } catch (\Exception $e) { - // HHVM compatibility: constructor throws on invalid resource $rb = null; } if (!$rb) { - throw new InvalidResourceException(sprintf('Cannot load resource "%s".', $resource)); + throw new InvalidResourceException(sprintf('Cannot load resource "%s"', $resource)); } elseif (intl_is_failure($rb->getErrorCode())) { throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode()); } diff --git a/vendor/symfony/translation/Loader/IcuResFileLoader.php b/vendor/symfony/translation/Loader/IcuResFileLoader.php index d5fe99603..005f26084 100644 --- a/vendor/symfony/translation/Loader/IcuResFileLoader.php +++ b/vendor/symfony/translation/Loader/IcuResFileLoader.php @@ -39,12 +39,11 @@ class IcuResFileLoader implements LoaderInterface try { $rb = new \ResourceBundle($locale, $resource); } catch (\Exception $e) { - // HHVM compatibility: constructor throws on invalid resource $rb = null; } if (!$rb) { - throw new InvalidResourceException(sprintf('Cannot load resource "%s".', $resource)); + throw new InvalidResourceException(sprintf('Cannot load resource "%s"', $resource)); } elseif (intl_is_failure($rb->getErrorCode())) { throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode()); } diff --git a/vendor/symfony/translation/Loader/JsonFileLoader.php b/vendor/symfony/translation/Loader/JsonFileLoader.php index 14d00d794..526721277 100644 --- a/vendor/symfony/translation/Loader/JsonFileLoader.php +++ b/vendor/symfony/translation/Loader/JsonFileLoader.php @@ -30,7 +30,7 @@ class JsonFileLoader extends FileLoader $messages = json_decode($data, true); if (0 < $errorCode = json_last_error()) { - throw new InvalidResourceException('Error parsing JSON: '.$this->getJSONErrorMessage($errorCode)); + throw new InvalidResourceException(sprintf('Error parsing JSON - %s', $this->getJSONErrorMessage($errorCode))); } } @@ -47,15 +47,15 @@ class JsonFileLoader extends FileLoader private function getJSONErrorMessage($errorCode) { switch ($errorCode) { - case \JSON_ERROR_DEPTH: + case JSON_ERROR_DEPTH: return 'Maximum stack depth exceeded'; - case \JSON_ERROR_STATE_MISMATCH: + case JSON_ERROR_STATE_MISMATCH: return 'Underflow or the modes mismatch'; - case \JSON_ERROR_CTRL_CHAR: + case JSON_ERROR_CTRL_CHAR: return 'Unexpected control character found'; - case \JSON_ERROR_SYNTAX: + case JSON_ERROR_SYNTAX: return 'Syntax error, malformed JSON'; - case \JSON_ERROR_UTF8: + case JSON_ERROR_UTF8: return 'Malformed UTF-8 characters, possibly incorrectly encoded'; default: return 'Unknown error'; diff --git a/vendor/symfony/translation/Loader/MoFileLoader.php b/vendor/symfony/translation/Loader/MoFileLoader.php index 4b249df02..d344c6e21 100644 --- a/vendor/symfony/translation/Loader/MoFileLoader.php +++ b/vendor/symfony/translation/Loader/MoFileLoader.php @@ -129,11 +129,8 @@ class MoFileLoader extends FileLoader * Reads an unsigned long from stream respecting endianness. * * @param resource $stream - * @param bool $isBigEndian - * - * @return int */ - private function readLong($stream, $isBigEndian) + private function readLong($stream, bool $isBigEndian): int { $result = unpack($isBigEndian ? 'N1' : 'V1', fread($stream, 4)); $result = current($result); diff --git a/vendor/symfony/translation/Loader/PhpFileLoader.php b/vendor/symfony/translation/Loader/PhpFileLoader.php index c361d5293..0991c3d3a 100644 --- a/vendor/symfony/translation/Loader/PhpFileLoader.php +++ b/vendor/symfony/translation/Loader/PhpFileLoader.php @@ -25,7 +25,7 @@ class PhpFileLoader extends FileLoader */ protected function loadResource($resource) { - if ([] === self::$cache && \function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN) && (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) || filter_var(ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) { + if ([] === self::$cache && \function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN) && (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) || filter_var(ini_get('opcache.enable_cli'), FILTER_VALIDATE_BOOLEAN))) { self::$cache = null; } diff --git a/vendor/symfony/translation/Loader/XliffFileLoader.php b/vendor/symfony/translation/Loader/XliffFileLoader.php index b728e70ba..6e01a7119 100644 --- a/vendor/symfony/translation/Loader/XliffFileLoader.php +++ b/vendor/symfony/translation/Loader/XliffFileLoader.php @@ -13,10 +13,10 @@ namespace Symfony\Component\Translation\Loader; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Config\Util\XmlUtils; -use Symfony\Component\Translation\Exception\InvalidArgumentException; use Symfony\Component\Translation\Exception\InvalidResourceException; use Symfony\Component\Translation\Exception\NotFoundResourceException; use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Util\XliffUtils; /** * XliffFileLoader loads translations from XLIFF files. @@ -53,11 +53,13 @@ class XliffFileLoader implements LoaderInterface try { $dom = XmlUtils::loadFile($resource); } catch (\InvalidArgumentException $e) { - throw new InvalidResourceException(sprintf('Unable to load "%s": ', $resource).$e->getMessage(), $e->getCode(), $e); + throw new InvalidResourceException(sprintf('Unable to load "%s": %s', $resource, $e->getMessage()), $e->getCode(), $e); } - $xliffVersion = $this->getVersionNumber($dom); - $this->validateSchema($xliffVersion, $dom, $this->getSchema($xliffVersion)); + $xliffVersion = XliffUtils::getVersionNumber($dom); + if ($errors = XliffUtils::validateSchema($dom)) { + throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: %s', $resource, XliffUtils::getErrorsAsString($errors))); + } if ('1.2' === $xliffVersion) { $this->extractXliff1($dom, $catalogue, $domain); @@ -75,50 +77,60 @@ class XliffFileLoader implements LoaderInterface * @param MessageCatalogue $catalogue Catalogue where we'll collect messages and metadata * @param string $domain The domain */ - private function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, $domain) + private function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain) { $xml = simplexml_import_dom($dom); $encoding = strtoupper($dom->encoding); - $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2'); - foreach ($xml->xpath('//xliff:trans-unit') as $translation) { - $attributes = $translation->attributes(); + $namespace = 'urn:oasis:names:tc:xliff:document:1.2'; + $xml->registerXPathNamespace('xliff', $namespace); - if (!(isset($attributes['resname']) || isset($translation->source))) { - continue; - } + foreach ($xml->xpath('//xliff:file') as $file) { + $fileAttributes = $file->attributes(); - $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source; - // If the xlf file has another encoding specified, try to convert it because - // simple_xml will always return utf-8 encoded values - $target = $this->utf8ToCharset((string) (isset($translation->target) ? $translation->target : $translation->source), $encoding); + $file->registerXPathNamespace('xliff', $namespace); - $catalogue->set((string) $source, $target, $domain); + foreach ($file->xpath('.//xliff:trans-unit') as $translation) { + $attributes = $translation->attributes(); - $metadata = []; - if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) { - $metadata['notes'] = $notes; - } - - if (isset($translation->target) && $translation->target->attributes()) { - $metadata['target-attributes'] = []; - foreach ($translation->target->attributes() as $key => $value) { - $metadata['target-attributes'][$key] = (string) $value; + if (!(isset($attributes['resname']) || isset($translation->source))) { + continue; } - } - if (isset($attributes['id'])) { - $metadata['id'] = (string) $attributes['id']; - } + $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source; + // If the xlf file has another encoding specified, try to convert it because + // simple_xml will always return utf-8 encoded values + $target = $this->utf8ToCharset((string) ($translation->target ?? $translation->source), $encoding); - $catalogue->setMetadata((string) $source, $metadata, $domain); + $catalogue->set((string) $source, $target, $domain); + + $metadata = [ + 'source' => (string) $translation->source, + 'file' => [ + 'original' => (string) $fileAttributes['original'], + ], + ]; + if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) { + $metadata['notes'] = $notes; + } + + if (isset($translation->target) && $translation->target->attributes()) { + $metadata['target-attributes'] = []; + foreach ($translation->target->attributes() as $key => $value) { + $metadata['target-attributes'][$key] = (string) $value; + } + } + + if (isset($attributes['id'])) { + $metadata['id'] = (string) $attributes['id']; + } + + $catalogue->setMetadata((string) $source, $metadata, $domain); + } } } - /** - * @param string $domain - */ - private function extractXliff2(\DOMDocument $dom, MessageCatalogue $catalogue, $domain) + private function extractXliff2(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain) { $xml = simplexml_import_dom($dom); $encoding = strtoupper($dom->encoding); @@ -162,13 +174,8 @@ class XliffFileLoader implements LoaderInterface /** * Convert a UTF8 string to the specified encoding. - * - * @param string $content String to decode - * @param string $encoding Target encoding - * - * @return string */ - private function utf8ToCharset($content, $encoding = null) + private function utf8ToCharset(string $content, string $encoding = null): string { if ('UTF-8' !== $encoding && !empty($encoding)) { return mb_convert_encoding($content, $encoding, 'UTF-8'); @@ -177,145 +184,7 @@ class XliffFileLoader implements LoaderInterface return $content; } - /** - * Validates and parses the given file into a DOMDocument. - * - * @param string $file - * @param string $schema source of the schema - * - * @throws InvalidResourceException - */ - private function validateSchema($file, \DOMDocument $dom, $schema) - { - $internalErrors = libxml_use_internal_errors(true); - - if (\LIBXML_VERSION < 20900) { - $disableEntities = libxml_disable_entity_loader(false); - $isValid = @$dom->schemaValidateSource($schema); - libxml_disable_entity_loader($disableEntities); - } else { - $isValid = @$dom->schemaValidateSource($schema); - } - - if (!$isValid) { - throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: ', $file).implode("\n", $this->getXmlErrors($internalErrors))); - } - - $dom->normalizeDocument(); - - libxml_clear_errors(); - libxml_use_internal_errors($internalErrors); - } - - private function getSchema($xliffVersion) - { - if ('1.2' === $xliffVersion) { - $schemaSource = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-1.2-strict.xsd'); - $xmlUri = 'http://www.w3.org/2001/xml.xsd'; - } elseif ('2.0' === $xliffVersion) { - $schemaSource = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-2.0.xsd'); - $xmlUri = 'informativeCopiesOf3rdPartySchemas/w3c/xml.xsd'; - } else { - throw new InvalidArgumentException(sprintf('No support implemented for loading XLIFF version "%s".', $xliffVersion)); - } - - return $this->fixXmlLocation($schemaSource, $xmlUri); - } - - /** - * Internally changes the URI of a dependent xsd to be loaded locally. - * - * @param string $schemaSource Current content of schema file - * @param string $xmlUri External URI of XML to convert to local - * - * @return string - */ - private function fixXmlLocation($schemaSource, $xmlUri) - { - $newPath = str_replace('\\', '/', __DIR__).'/schema/dic/xliff-core/xml.xsd'; - $parts = explode('/', $newPath); - $locationstart = 'file:///'; - if (0 === stripos($newPath, 'phar://')) { - $tmpfile = tempnam(sys_get_temp_dir(), 'symfony'); - if ($tmpfile) { - copy($newPath, $tmpfile); - $parts = explode('/', str_replace('\\', '/', $tmpfile)); - } else { - array_shift($parts); - $locationstart = 'phar:///'; - } - } - - $drive = '\\' === \DIRECTORY_SEPARATOR ? array_shift($parts).'/' : ''; - $newPath = $locationstart.$drive.implode('/', array_map('rawurlencode', $parts)); - - return str_replace($xmlUri, $newPath, $schemaSource); - } - - /** - * Returns the XML errors of the internal XML parser. - * - * @param bool $internalErrors - * - * @return array An array of errors - */ - private function getXmlErrors($internalErrors) - { - $errors = []; - foreach (libxml_get_errors() as $error) { - $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', - \LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', - $error->code, - trim($error->message), - $error->file ?: 'n/a', - $error->line, - $error->column - ); - } - - libxml_clear_errors(); - libxml_use_internal_errors($internalErrors); - - return $errors; - } - - /** - * Gets xliff file version based on the root "version" attribute. - * Defaults to 1.2 for backwards compatibility. - * - * @throws InvalidArgumentException - * - * @return string - */ - private function getVersionNumber(\DOMDocument $dom) - { - /** @var \DOMNode $xliff */ - foreach ($dom->getElementsByTagName('xliff') as $xliff) { - $version = $xliff->attributes->getNamedItem('version'); - if ($version) { - return $version->nodeValue; - } - - $namespace = $xliff->attributes->getNamedItem('xmlns'); - if ($namespace) { - if (0 !== substr_compare('urn:oasis:names:tc:xliff:document:', $namespace->nodeValue, 0, 34)) { - throw new InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s".', $namespace)); - } - - return substr($namespace, 34); - } - } - - // Falls back to v1.2 - return '1.2'; - } - - /** - * @param string|null $encoding - * - * @return array - */ - private function parseNotesMetadata(\SimpleXMLElement $noteElement = null, $encoding = null) + private function parseNotesMetadata(\SimpleXMLElement $noteElement = null, string $encoding = null): array { $notes = []; diff --git a/vendor/symfony/translation/Loader/YamlFileLoader.php b/vendor/symfony/translation/Loader/YamlFileLoader.php index 4040b2dfa..438d7d764 100644 --- a/vendor/symfony/translation/Loader/YamlFileLoader.php +++ b/vendor/symfony/translation/Loader/YamlFileLoader.php @@ -15,6 +15,7 @@ use Symfony\Component\Translation\Exception\InvalidResourceException; use Symfony\Component\Translation\Exception\LogicException; use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Parser as YamlParser; +use Symfony\Component\Yaml\Yaml; /** * YamlFileLoader loads translations from Yaml files. @@ -38,18 +39,10 @@ class YamlFileLoader extends FileLoader $this->yamlParser = new YamlParser(); } - $prevErrorHandler = set_error_handler(function ($level, $message, $script, $line) use ($resource, &$prevErrorHandler) { - $message = \E_USER_DEPRECATED === $level ? preg_replace('/ on line \d+/', ' in "'.$resource.'"$0', $message) : $message; - - return $prevErrorHandler ? $prevErrorHandler($level, $message, $script, $line) : false; - }); - try { - $messages = $this->yamlParser->parseFile($resource); + $messages = $this->yamlParser->parseFile($resource, Yaml::PARSE_CONSTANT); } catch (ParseException $e) { - throw new InvalidResourceException(sprintf('The file "%s" does not contain valid YAML: ', $resource).$e->getMessage(), 0, $e); - } finally { - restore_error_handler(); + throw new InvalidResourceException(sprintf('Error parsing YAML, invalid file "%s"', $resource), 0, $e); } if (null !== $messages && !\is_array($messages)) { diff --git a/vendor/symfony/translation/LoggingTranslator.php b/vendor/symfony/translation/LoggingTranslator.php index 942736ea7..bcad1ce2c 100644 --- a/vendor/symfony/translation/LoggingTranslator.php +++ b/vendor/symfony/translation/LoggingTranslator.php @@ -13,11 +13,14 @@ namespace Symfony\Component\Translation; use Psr\Log\LoggerInterface; use Symfony\Component\Translation\Exception\InvalidArgumentException; +use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; +use Symfony\Contracts\Translation\LocaleAwareInterface; +use Symfony\Contracts\Translation\TranslatorInterface; /** * @author Abdellatif Ait boudad */ -class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface +class LoggingTranslator implements TranslatorInterface, LegacyTranslatorInterface, TranslatorBagInterface { /** * @var TranslatorInterface|TranslatorBagInterface @@ -29,10 +32,13 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface /** * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface */ - public function __construct(TranslatorInterface $translator, LoggerInterface $logger) + public function __construct($translator, LoggerInterface $logger) { - if (!$translator instanceof TranslatorBagInterface) { - throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', \get_class($translator))); + if (!$translator instanceof LegacyTranslatorInterface && !$translator instanceof TranslatorInterface) { + throw new \TypeError(sprintf('Argument 1 passed to %s() must be an instance of %s, %s given.', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator))); + } + if (!$translator instanceof TranslatorBagInterface || !$translator instanceof LocaleAwareInterface) { + throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface, TranslatorBagInterface and LocaleAwareInterface.', \get_class($translator))); } $this->translator = $translator; @@ -52,10 +58,19 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2, use the trans() method instead with a %count% parameter */ public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null) { - $trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale); + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the trans() one instead with a "%%count%%" parameter.', __METHOD__), E_USER_DEPRECATED); + + if ($this->translator instanceof TranslatorInterface) { + $trans = $this->translator->trans($id, ['%count%' => $number] + $parameters, $domain, $locale); + } else { + $trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale); + } + $this->log($id, $domain, $locale); return $trans; @@ -66,7 +81,13 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface */ public function setLocale($locale) { + $prev = $this->translator->getLocale(); $this->translator->setLocale($locale); + if ($prev === $locale) { + return; + } + + $this->logger->debug(sprintf('The locale of the translator has changed from "%s" to "%s".', $prev, $locale)); } /** @@ -104,7 +125,7 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface */ public function __call($method, $args) { - return \call_user_func_array([$this->translator, $method], $args); + return $this->translator->{$method}(...$args); } /** diff --git a/vendor/symfony/translation/MessageCatalogue.php b/vendor/symfony/translation/MessageCatalogue.php index a9a24b12a..3c0f41adf 100644 --- a/vendor/symfony/translation/MessageCatalogue.php +++ b/vendor/symfony/translation/MessageCatalogue.php @@ -30,7 +30,7 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf * @param string $locale The locale * @param array $messages An array of messages classified by domain */ - public function __construct($locale, array $messages = []) + public function __construct(?string $locale, array $messages = []) { $this->locale = $locale; $this->messages = $messages; @@ -49,7 +49,17 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf */ public function getDomains() { - return array_keys($this->messages); + $domains = []; + $suffixLength = \strlen(self::INTL_DOMAIN_SUFFIX); + + foreach ($this->messages as $domain => $messages) { + if (\strlen($domain) > $suffixLength && false !== $i = strpos($domain, self::INTL_DOMAIN_SUFFIX, -$suffixLength)) { + $domain = substr($domain, 0, $i); + } + $domains[$domain] = $domain; + } + + return array_values($domains); } /** @@ -57,11 +67,23 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf */ public function all($domain = null) { - if (null === $domain) { - return $this->messages; + if (null !== $domain) { + return ($this->messages[$domain.self::INTL_DOMAIN_SUFFIX] ?? []) + ($this->messages[$domain] ?? []); } - return isset($this->messages[$domain]) ? $this->messages[$domain] : []; + $allMessages = []; + $suffixLength = \strlen(self::INTL_DOMAIN_SUFFIX); + + foreach ($this->messages as $domain => $messages) { + if (\strlen($domain) > $suffixLength && false !== $i = strpos($domain, self::INTL_DOMAIN_SUFFIX, -$suffixLength)) { + $domain = substr($domain, 0, $i); + $allMessages[$domain] = $messages + ($allMessages[$domain] ?? []); + } else { + $allMessages[$domain] = ($allMessages[$domain] ?? []) + $messages; + } + } + + return $allMessages; } /** @@ -77,7 +99,7 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf */ public function has($id, $domain = 'messages') { - if (isset($this->messages[$domain][$id])) { + if (isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) { return true; } @@ -93,7 +115,7 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf */ public function defines($id, $domain = 'messages') { - return isset($this->messages[$domain][$id]); + return isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id]); } /** @@ -101,6 +123,10 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf */ public function get($id, $domain = 'messages') { + if (isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) { + return $this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id]; + } + if (isset($this->messages[$domain][$id])) { return $this->messages[$domain][$id]; } @@ -117,7 +143,7 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf */ public function replace($messages, $domain = 'messages') { - $this->messages[$domain] = []; + unset($this->messages[$domain], $this->messages[$domain.self::INTL_DOMAIN_SUFFIX]); $this->add($messages, $domain); } @@ -142,10 +168,14 @@ class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterf public function addCatalogue(MessageCatalogueInterface $catalogue) { if ($catalogue->getLocale() !== $this->locale) { - throw new LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s".', $catalogue->getLocale(), $this->locale)); + throw new LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s"', $catalogue->getLocale(), $this->locale)); } foreach ($catalogue->all() as $domain => $messages) { + if ($intlMessages = $catalogue->all($domain.self::INTL_DOMAIN_SUFFIX)) { + $this->add($intlMessages, $domain.self::INTL_DOMAIN_SUFFIX); + $messages = array_diff_key($messages, $intlMessages); + } $this->add($messages, $domain); } diff --git a/vendor/symfony/translation/MessageCatalogueInterface.php b/vendor/symfony/translation/MessageCatalogueInterface.php index e0dbb2bd9..f3d3f5ea9 100644 --- a/vendor/symfony/translation/MessageCatalogueInterface.php +++ b/vendor/symfony/translation/MessageCatalogueInterface.php @@ -20,6 +20,8 @@ use Symfony\Component\Config\Resource\ResourceInterface; */ interface MessageCatalogueInterface { + const INTL_DOMAIN_SUFFIX = '+intl-icu'; + /** * Gets the catalogue locale. * diff --git a/vendor/symfony/translation/MessageSelector.php b/vendor/symfony/translation/MessageSelector.php index a7743ebae..0f0febb8b 100644 --- a/vendor/symfony/translation/MessageSelector.php +++ b/vendor/symfony/translation/MessageSelector.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Translation; +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.2, use IdentityTranslator instead.', MessageSelector::class), E_USER_DEPRECATED); + use Symfony\Component\Translation\Exception\InvalidArgumentException; /** @@ -18,6 +20,8 @@ use Symfony\Component\Translation\Exception\InvalidArgumentException; * * @author Fabien Potencier * @author Bernhard Schussek + * + * @deprecated since Symfony 4.2, use IdentityTranslator instead. */ class MessageSelector { @@ -39,9 +43,9 @@ class MessageSelector * The two methods can also be mixed: * {0} There are no apples|one: There is one apple|more: There are %count% apples * - * @param string $message The message being translated - * @param int $number The number of items represented for the message - * @param string $locale The locale to use for choosing + * @param string $message The message being translated + * @param int|float $number The number of items represented for the message + * @param string $locale The locale to use for choosing * * @return string * diff --git a/vendor/symfony/translation/PluralizationRules.php b/vendor/symfony/translation/PluralizationRules.php index d369f5f3f..77c276073 100644 --- a/vendor/symfony/translation/PluralizationRules.php +++ b/vendor/symfony/translation/PluralizationRules.php @@ -15,6 +15,8 @@ namespace Symfony\Component\Translation; * Returns the plural rules for a given locale. * * @author Fabien Potencier + * + * @deprecated since Symfony 4.2, use IdentityTranslator instead */ class PluralizationRules { @@ -28,8 +30,12 @@ class PluralizationRules * * @return int The plural position */ - public static function get($number, $locale) + public static function get($number, $locale/*, bool $triggerDeprecation = true*/) { + if (3 > \func_num_args() || func_get_arg(2)) { + @trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.2.', __CLASS__), E_USER_DEPRECATED); + } + if ('pt_BR' === $locale) { // temporary set a locale for brazilian $locale = 'xbr'; @@ -40,7 +46,7 @@ class PluralizationRules } if (isset(self::$rules[$locale])) { - $return = \call_user_func(self::$rules[$locale], $number); + $return = self::$rules[$locale]($number); if (!\is_int($return) || $return < 0) { return 0; @@ -196,6 +202,8 @@ class PluralizationRules */ public static function set(callable $rule, $locale) { + @trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.2.', __CLASS__), E_USER_DEPRECATED); + if ('pt_BR' === $locale) { // temporary set a locale for brazilian $locale = 'xbr'; diff --git a/vendor/symfony/translation/README.md b/vendor/symfony/translation/README.md index f4f170667..e80a70cad 100644 --- a/vendor/symfony/translation/README.md +++ b/vendor/symfony/translation/README.md @@ -3,28 +3,10 @@ Translation Component The Translation component provides tools to internationalize your application. -Getting Started ---------------- - -``` -$ composer require symfony/translation -``` - -```php -use Symfony\Component\Translation\Translator; - -$translator = new Translator('fr_FR'); -$translator->addResource('array', [ - 'Hello World!' => 'Bonjour !', -], 'fr_FR'); - -echo $translator->trans('Hello World!'); // outputs « Bonjour ! » -``` - Resources --------- - * [Documentation](https://symfony.com/doc/current/translation.html) + * [Documentation](https://symfony.com/doc/current/components/translation.html) * [Contributing](https://symfony.com/doc/current/contributing/index.html) * [Report issues](https://github.com/symfony/symfony/issues) and [send Pull Requests](https://github.com/symfony/symfony/pulls) diff --git a/vendor/symfony/translation/Resources/bin/translation-status.php b/vendor/symfony/translation/Resources/bin/translation-status.php index e3e644963..44918c92e 100644 --- a/vendor/symfony/translation/Resources/bin/translation-status.php +++ b/vendor/symfony/translation/Resources/bin/translation-status.php @@ -61,7 +61,7 @@ foreach (array_slice($argv, 1) as $argumentOrOption) { foreach ($config['original_files'] as $originalFilePath) { if (!file_exists($originalFilePath)) { - echo sprintf('The following file does not exist. Make sure that you execute this command at the root dir of the Symfony code repository.%s %s', \PHP_EOL, $originalFilePath); + echo sprintf('The following file does not exist. Make sure that you execute this command at the root dir of the Symfony code repository.%s %s', PHP_EOL, $originalFilePath); exit(1); } } @@ -89,7 +89,7 @@ function findTranslationFiles($originalFilePath, $localeToAnalyze) $originalFileName = basename($originalFilePath); $translationFileNamePattern = str_replace('.en.', '.*.', $originalFileName); - $translationFiles = glob($translationsDir.'/'.$translationFileNamePattern, \GLOB_NOSORT); + $translationFiles = glob($translationsDir.'/'.$translationFileNamePattern, GLOB_NOSORT); sort($translationFiles); foreach ($translationFiles as $filePath) { $locale = extractLocaleFromFilePath($filePath); @@ -127,7 +127,7 @@ function printTranslationStatus($originalFilePath, $translationStatus, $verboseO { printTitle($originalFilePath); printTable($translationStatus, $verboseOutput); - echo \PHP_EOL.\PHP_EOL; + echo PHP_EOL.PHP_EOL; } function extractLocaleFromFilePath($filePath) @@ -154,8 +154,8 @@ function extractTranslationKeys($filePath) function printTitle($title) { - echo $title.\PHP_EOL; - echo str_repeat('=', strlen($title)).\PHP_EOL.\PHP_EOL; + echo $title.PHP_EOL; + echo str_repeat('=', strlen($title)).PHP_EOL.PHP_EOL; } function printTable($translations, $verboseOutput) @@ -174,19 +174,19 @@ function printTable($translations, $verboseOutput) textColorGreen(); } - echo sprintf('| Locale: %-'.$longestLocaleNameLength.'s | Translated: %d/%d', $locale, $translation['translated'], $translation['total']).\PHP_EOL; + echo sprintf('| Locale: %-'.$longestLocaleNameLength.'s | Translated: %d/%d', $locale, $translation['translated'], $translation['total']).PHP_EOL; textColorNormal(); if (true === $verboseOutput && count($translation['missingKeys']) > 0) { - echo str_repeat('-', 80).\PHP_EOL; - echo '| Missing Translations:'.\PHP_EOL; + echo str_repeat('-', 80).PHP_EOL; + echo '| Missing Translations:'.PHP_EOL; foreach ($translation['missingKeys'] as $id => $content) { - echo sprintf('| (id=%s) %s', $id, $content).\PHP_EOL; + echo sprintf('| (id=%s) %s', $id, $content).PHP_EOL; } - echo str_repeat('-', 80).\PHP_EOL; + echo str_repeat('-', 80).PHP_EOL; } } } diff --git a/vendor/symfony/translation/Resources/data/parents.json b/vendor/symfony/translation/Resources/data/parents.json index d334b2982..6e45d9f38 100644 --- a/vendor/symfony/translation/Resources/data/parents.json +++ b/vendor/symfony/translation/Resources/data/parents.json @@ -117,7 +117,6 @@ "es_US": "es_419", "es_UY": "es_419", "es_VE": "es_419", - "ff_Adlm": "root", "pa_Arab": "root", "pt_AO": "pt_PT", "pt_CH": "pt_PT", @@ -129,7 +128,6 @@ "pt_MZ": "pt_PT", "pt_ST": "pt_PT", "pt_TL": "pt_PT", - "sd_Deva": "root", "sr_Latn": "root", "uz_Arab": "root", "uz_Cyrl": "root", diff --git a/vendor/symfony/translation/Tests/Catalogue/MergeOperationTest.php b/vendor/symfony/translation/Tests/Catalogue/MergeOperationTest.php index 0dc68beb9..22af86e90 100644 --- a/vendor/symfony/translation/Tests/Catalogue/MergeOperationTest.php +++ b/vendor/symfony/translation/Tests/Catalogue/MergeOperationTest.php @@ -53,6 +53,20 @@ class MergeOperationTest extends AbstractOperationTest ); } + public function testGetResultFromIntlDomain() + { + $this->assertEquals( + new MessageCatalogue('en', [ + 'messages' => ['a' => 'old_a', 'b' => 'old_b'], + 'messages+intl-icu' => ['d' => 'old_d', 'c' => 'new_c'], + ]), + $this->createOperation( + new MessageCatalogue('en', ['messages' => ['a' => 'old_a', 'b' => 'old_b'], 'messages+intl-icu' => ['d' => 'old_d']]), + new MessageCatalogue('en', ['messages+intl-icu' => ['a' => 'new_a', 'c' => 'new_c']]) + )->getResult() + ); + } + public function testGetResultWithMetadata() { $leftCatalogue = new MessageCatalogue('en', ['messages' => ['a' => 'old_a', 'b' => 'old_b']]); diff --git a/vendor/symfony/translation/Tests/Catalogue/TargetOperationTest.php b/vendor/symfony/translation/Tests/Catalogue/TargetOperationTest.php index 8077ff095..570b503ae 100644 --- a/vendor/symfony/translation/Tests/Catalogue/TargetOperationTest.php +++ b/vendor/symfony/translation/Tests/Catalogue/TargetOperationTest.php @@ -53,6 +53,20 @@ class TargetOperationTest extends AbstractOperationTest ); } + public function testGetResultFromIntlDomain() + { + $this->assertEquals( + new MessageCatalogue('en', [ + 'messages' => ['a' => 'old_a'], + 'messages+intl-icu' => ['c' => 'new_c'], + ]), + $this->createOperation( + new MessageCatalogue('en', ['messages' => ['a' => 'old_a'], 'messages+intl-icu' => ['b' => 'old_b']]), + new MessageCatalogue('en', ['messages' => ['a' => 'new_a'], 'messages+intl-icu' => ['c' => 'new_c']]) + )->getResult() + ); + } + public function testGetResultWithMetadata() { $leftCatalogue = new MessageCatalogue('en', ['messages' => ['a' => 'old_a', 'b' => 'old_b']]); diff --git a/vendor/symfony/translation/Tests/Command/XliffLintCommandTest.php b/vendor/symfony/translation/Tests/Command/XliffLintCommandTest.php new file mode 100644 index 000000000..a951d3466 --- /dev/null +++ b/vendor/symfony/translation/Tests/Command/XliffLintCommandTest.php @@ -0,0 +1,205 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\Translation\Command\XliffLintCommand; + +/** + * Tests the XliffLintCommand. + * + * @author Javier Eguiluz + */ +class XliffLintCommandTest extends TestCase +{ + private $files; + + public function testLintCorrectFile() + { + $tester = $this->createCommandTester(); + $filename = $this->createFile(); + + $tester->execute( + ['filename' => $filename], + ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false] + ); + + $this->assertEquals(0, $tester->getStatusCode(), 'Returns 0 in case of success'); + $this->assertStringContainsString('OK', trim($tester->getDisplay())); + } + + public function testLintCorrectFiles() + { + $tester = $this->createCommandTester(); + $filename1 = $this->createFile(); + $filename2 = $this->createFile(); + + $tester->execute( + ['filename' => [$filename1, $filename2]], + ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false] + ); + + $this->assertEquals(0, $tester->getStatusCode(), 'Returns 0 in case of success'); + $this->assertStringContainsString('OK', trim($tester->getDisplay())); + } + + /** + * @dataProvider provideStrictFilenames + */ + public function testStrictFilenames($requireStrictFileNames, $fileNamePattern, $targetLanguage, $mustFail) + { + $tester = $this->createCommandTester($requireStrictFileNames); + $filename = $this->createFile('note', $targetLanguage, $fileNamePattern); + + $tester->execute( + ['filename' => $filename], + ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false] + ); + + $this->assertEquals($mustFail ? 1 : 0, $tester->getStatusCode()); + $this->assertStringContainsString($mustFail ? '[WARNING] 0 XLIFF files have valid syntax and 1 contain errors.' : '[OK] All 1 XLIFF files contain valid syntax.', $tester->getDisplay()); + } + + public function testLintIncorrectXmlSyntax() + { + $tester = $this->createCommandTester(); + $filename = $this->createFile('note '); + + $tester->execute(['filename' => $filename], ['decorated' => false]); + + $this->assertEquals(1, $tester->getStatusCode(), 'Returns 1 in case of error'); + $this->assertStringContainsString('Opening and ending tag mismatch: target line 6 and source', trim($tester->getDisplay())); + } + + public function testLintIncorrectTargetLanguage() + { + $tester = $this->createCommandTester(); + $filename = $this->createFile('note', 'es'); + + $tester->execute(['filename' => $filename], ['decorated' => false]); + + $this->assertEquals(1, $tester->getStatusCode(), 'Returns 1 in case of error'); + $this->assertStringContainsString('There is a mismatch between the language included in the file name ("messages.en.xlf") and the "es" value used in the "target-language" attribute of the file.', trim($tester->getDisplay())); + } + + public function testLintTargetLanguageIsCaseInsensitive() + { + $tester = $this->createCommandTester(); + $filename = $this->createFile('note', 'zh-cn', 'messages.zh_CN.xlf'); + + $tester->execute(['filename' => $filename], ['decorated' => false]); + + $this->assertEquals(0, $tester->getStatusCode()); + $this->assertStringContainsString('[OK] All 1 XLIFF files contain valid syntax.', trim($tester->getDisplay())); + } + + public function testLintFileNotReadable() + { + $this->expectException('RuntimeException'); + $tester = $this->createCommandTester(); + $filename = $this->createFile(); + unlink($filename); + + $tester->execute(['filename' => $filename], ['decorated' => false]); + } + + public function testGetHelp() + { + $command = new XliffLintCommand(); + $expected = <<php %command.full_name% dirname + php %command.full_name% dirname --format=json + +EOF; + + $this->assertStringContainsString($expected, $command->getHelp()); + } + + /** + * @return string Path to the new file + */ + private function createFile($sourceContent = 'note', $targetLanguage = 'en', $fileNamePattern = 'messages.%locale%.xlf') + { + $xliffContent = << + + + + + $sourceContent + NOTE + + + + +XLIFF; + + $filename = sprintf('%s/translation-xliff-lint-test/%s', sys_get_temp_dir(), str_replace('%locale%', 'en', $fileNamePattern)); + file_put_contents($filename, $xliffContent); + + $this->files[] = $filename; + + return $filename; + } + + /** + * @return CommandTester + */ + private function createCommandTester($requireStrictFileNames = true, $application = null) + { + if (!$application) { + $application = new Application(); + $application->add(new XliffLintCommand(null, null, null, $requireStrictFileNames)); + } + + $command = $application->find('lint:xliff'); + + if ($application) { + $command->setApplication($application); + } + + return new CommandTester($command); + } + + protected function setUp(): void + { + $this->files = []; + @mkdir(sys_get_temp_dir().'/translation-xliff-lint-test'); + } + + protected function tearDown(): void + { + foreach ($this->files as $file) { + if (file_exists($file)) { + unlink($file); + } + } + rmdir(sys_get_temp_dir().'/translation-xliff-lint-test'); + } + + public function provideStrictFilenames() + { + yield [false, 'messages.%locale%.xlf', 'en', false]; + yield [false, 'messages.%locale%.xlf', 'es', true]; + yield [false, '%locale%.messages.xlf', 'en', false]; + yield [false, '%locale%.messages.xlf', 'es', true]; + yield [true, 'messages.%locale%.xlf', 'en', false]; + yield [true, 'messages.%locale%.xlf', 'es', true]; + yield [true, '%locale%.messages.xlf', 'en', true]; + yield [true, '%locale%.messages.xlf', 'es', true]; + } +} diff --git a/vendor/symfony/translation/Tests/DataCollector/TranslationDataCollectorTest.php b/vendor/symfony/translation/Tests/DataCollector/TranslationDataCollectorTest.php index bd97a2445..1a600c8c6 100644 --- a/vendor/symfony/translation/Tests/DataCollector/TranslationDataCollectorTest.php +++ b/vendor/symfony/translation/Tests/DataCollector/TranslationDataCollectorTest.php @@ -17,7 +17,7 @@ use Symfony\Component\Translation\DataCollectorTranslator; class TranslationDataCollectorTest extends TestCase { - protected function setUp() + protected function setUp(): void { if (!class_exists('Symfony\Component\HttpKernel\DataCollector\DataCollector')) { $this->markTestSkipped('The "DataCollector" is not available'); diff --git a/vendor/symfony/translation/Tests/DataCollectorTranslatorTest.php b/vendor/symfony/translation/Tests/DataCollectorTranslatorTest.php index 5cb7c31a4..d3de1e259 100644 --- a/vendor/symfony/translation/Tests/DataCollectorTranslatorTest.php +++ b/vendor/symfony/translation/Tests/DataCollectorTranslatorTest.php @@ -25,7 +25,7 @@ class DataCollectorTranslatorTest extends TestCase $collector->trans('foo'); $collector->trans('bar'); - $collector->transChoice('choice', 0); + $collector->trans('choice', ['%count%' => 0]); $collector->trans('bar_ru'); $collector->trans('bar_ru', ['foo' => 'bar']); @@ -57,7 +57,7 @@ class DataCollectorTranslatorTest extends TestCase 'fallbackLocale' => null, 'domain' => 'messages', 'state' => DataCollectorTranslator::MESSAGE_MISSING, - 'parameters' => [], + 'parameters' => ['%count%' => 0], 'transChoiceNumber' => 0, ]; $expectedMessages[] = [ @@ -84,6 +84,31 @@ class DataCollectorTranslatorTest extends TestCase $this->assertEquals($expectedMessages, $collector->getCollectedMessages()); } + /** + * @group legacy + */ + public function testCollectMessagesTransChoice() + { + $collector = $this->createCollector(); + $collector->setFallbackLocales(['fr', 'ru']); + $collector->transChoice('choice', 0); + + $expectedMessages = []; + + $expectedMessages[] = [ + 'id' => 'choice', + 'translation' => 'choice', + 'locale' => 'en', + 'fallbackLocale' => null, + 'domain' => 'messages', + 'state' => DataCollectorTranslator::MESSAGE_MISSING, + 'parameters' => ['%count%' => 0], + 'transChoiceNumber' => 0, + ]; + + $this->assertEquals($expectedMessages, $collector->getCollectedMessages()); + } + private function createCollector() { $translator = new Translator('en'); diff --git a/vendor/symfony/translation/Tests/DependencyInjection/TranslationPassTest.php b/vendor/symfony/translation/Tests/DependencyInjection/TranslationPassTest.php index 96ec62502..f62fc85eb 100644 --- a/vendor/symfony/translation/Tests/DependencyInjection/TranslationPassTest.php +++ b/vendor/symfony/translation/Tests/DependencyInjection/TranslationPassTest.php @@ -55,49 +55,68 @@ class TranslationPassTest extends TestCase $this->assertEquals($expected, $container->getDefinition((string) $translator->getArgument(0))->getArgument(0)); } - /** - * @group legacy - * @expectedDeprecation The default value for $readerServiceId in "Symfony\Component\Translation\DependencyInjection\TranslatorPass::__construct()" will change in 4.0 to "translation.reader". - * - * A test that verifies the deprecated "translation.loader" gets the LoaderInterfaces added. - * - * This test should be removed in 4.0. - */ - public function testValidCollectorWithDeprecatedTranslationLoader() + public function testValidCommandsViewPathsArgument() { - $loader = (new Definition()) - ->addTag('translation.loader', ['alias' => 'xliff', 'legacy-alias' => 'xlf']); - - $legacyReader = new Definition(); - $reader = new Definition(); - - $translator = (new Definition()) - ->setArguments([null, null, null, null]); - $container = new ContainerBuilder(); - $container->setDefinition('translator.default', $translator); - $container->setDefinition('translation.loader', $legacyReader); - $container->setDefinition('translation.reader', $reader); - $container->setDefinition('translation.xliff_loader', $loader); + $container->register('translator.default') + ->setArguments([null, null, null, null]) + ; + $debugCommand = $container->register('console.command.translation_debug') + ->setArguments([null, null, null, null, null, [], []]) + ; + $updateCommand = $container->register('console.command.translation_update') + ->setArguments([null, null, null, null, null, null, [], []]) + ; + $container->register('twig.template_iterator') + ->setArguments([null, null, ['other/templates' => null, 'tpl' => 'App']]) + ; + $container->setParameter('twig.default_path', 'templates'); - $pass = new TranslatorPass(); + $pass = new TranslatorPass('translator.default'); $pass->process($container); - $expectedReader = (new Definition()) - ->addMethodCall('addLoader', ['xliff', new Reference('translation.xliff_loader')]) - ->addMethodCall('addLoader', ['xlf', new Reference('translation.xliff_loader')]) + $expectedViewPaths = ['other/templates', 'tpl']; + + $this->assertSame('templates', $debugCommand->getArgument(4)); + $this->assertSame('templates', $updateCommand->getArgument(5)); + $this->assertSame($expectedViewPaths, $debugCommand->getArgument(6)); + $this->assertSame($expectedViewPaths, $updateCommand->getArgument(7)); + } + + public function testCommandsViewPathsArgumentsAreIgnoredWithOldServiceDefinitions() + { + $container = new ContainerBuilder(); + $container->register('translator.default') + ->setArguments([null, null, null, null]) ; - $this->assertEquals($expectedReader, $legacyReader); - $this->assertEquals($expectedReader, $reader); - - $expectedLoader = (new Definition()) - ->addTag('translation.loader', ['alias' => 'xliff', 'legacy-alias' => 'xlf']) + $debugCommand = $container->register('console.command.translation_debug') + ->setArguments([ + new Reference('translator'), + new Reference('translation.reader'), + new Reference('translation.extractor'), + '%translator.default_path%', + null, + ]) ; - $this->assertEquals($expectedLoader, $loader); + $updateCommand = $container->register('console.command.translation_update') + ->setArguments([ + new Reference('translation.writer'), + new Reference('translation.reader'), + new Reference('translation.extractor'), + '%kernel.default_locale%', + '%translator.default_path%', + null, + ]) + ; + $container->register('twig.template_iterator') + ->setArguments([null, null, ['other/templates' => null, 'tpl' => 'App']]) + ; + $container->setParameter('twig.default_path', 'templates'); - $this->assertSame(['translation.xliff_loader' => ['xliff', 'xlf']], $translator->getArgument(3)); + $pass = new TranslatorPass('translator.default'); + $pass->process($container); - $expected = ['translation.xliff_loader' => new ServiceClosureArgument(new Reference('translation.xliff_loader'))]; - $this->assertEquals($expected, $container->getDefinition((string) $translator->getArgument(0))->getArgument(0)); + $this->assertSame('templates', $debugCommand->getArgument(4)); + $this->assertSame('templates', $updateCommand->getArgument(5)); } } diff --git a/vendor/symfony/translation/Tests/DependencyInjection/TranslationPathsPassTest.php b/vendor/symfony/translation/Tests/DependencyInjection/TranslationPathsPassTest.php new file mode 100644 index 000000000..42ab398df --- /dev/null +++ b/vendor/symfony/translation/Tests/DependencyInjection/TranslationPathsPassTest.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Tests\DependencyInjection; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceLocator; +use Symfony\Component\Translation\DependencyInjection\TranslatorPathsPass; +use Symfony\Component\Translation\Tests\DependencyInjection\fixtures\ControllerArguments; +use Symfony\Component\Translation\Tests\DependencyInjection\fixtures\ServiceArguments; +use Symfony\Component\Translation\Tests\DependencyInjection\fixtures\ServiceMethodCalls; +use Symfony\Component\Translation\Tests\DependencyInjection\fixtures\ServiceProperties; +use Symfony\Component\Translation\Tests\DependencyInjection\fixtures\ServiceSubscriber; + +class TranslationPathsPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container->register('translator'); + $debugCommand = $container->register('console.command.translation_debug') + ->setArguments([null, null, null, null, null, [], []]) + ; + $updateCommand = $container->register('console.command.translation_update') + ->setArguments([null, null, null, null, null, null, [], []]) + ; + $container->register(ControllerArguments::class, ControllerArguments::class) + ->setTags(['controller.service_arguments']) + ; + $container->register(ServiceArguments::class, ServiceArguments::class) + ->setArguments([new Reference('translator')]) + ; + $container->register(ServiceProperties::class, ServiceProperties::class) + ->setProperties([new Reference('translator')]) + ; + $container->register(ServiceMethodCalls::class, ServiceMethodCalls::class) + ->setMethodCalls([['setTranslator', [new Reference('translator')]]]) + ; + $container->register('service_rc') + ->setArguments([new Definition(), new Reference(ServiceMethodCalls::class)]) + ; + $serviceLocator1 = $container->register('.service_locator.foo', ServiceLocator::class) + ->setArguments([new ServiceClosureArgument(new Reference('translator'))]) + ; + $serviceLocator2 = (new Definition(ServiceLocator::class)) + ->setArguments([ServiceSubscriber::class, new Reference('service_container')]) + ->setFactory([$serviceLocator1, 'withContext']) + ; + $container->register('service_subscriber', ServiceSubscriber::class) + ->setArguments([$serviceLocator2]) + ; + $container->register('.service_locator.bar', ServiceLocator::class) + ->setArguments([[ + ControllerArguments::class.'::index' => new ServiceClosureArgument(new Reference('.service_locator.foo')), + ControllerArguments::class.'::__invoke' => new ServiceClosureArgument(new Reference('.service_locator.foo')), + ControllerArguments::class => new ServiceClosureArgument(new Reference('.service_locator.foo')), + ]]) + ; + $container->register('argument_resolver.service') + ->setArguments([new Reference('.service_locator.bar')]) + ; + + $pass = new TranslatorPathsPass('translator', 'console.command.translation_debug', 'console.command.translation_update', 'argument_resolver.service'); + $pass->process($container); + + $expectedPaths = [ + $container->getReflectionClass(ServiceArguments::class)->getFileName(), + $container->getReflectionClass(ServiceProperties::class)->getFileName(), + $container->getReflectionClass(ServiceMethodCalls::class)->getFileName(), + $container->getReflectionClass(ControllerArguments::class)->getFileName(), + $container->getReflectionClass(ServiceSubscriber::class)->getFileName(), + ]; + + $this->assertSame($expectedPaths, $debugCommand->getArgument(6)); + $this->assertSame($expectedPaths, $updateCommand->getArgument(7)); + } +} diff --git a/vendor/symfony/translation/Tests/DependencyInjection/fixtures/ControllerArguments.php b/vendor/symfony/translation/Tests/DependencyInjection/fixtures/ControllerArguments.php new file mode 100644 index 000000000..97a53fa76 --- /dev/null +++ b/vendor/symfony/translation/Tests/DependencyInjection/fixtures/ControllerArguments.php @@ -0,0 +1,16 @@ + TranslatorInterface::class]; + } +} diff --git a/vendor/symfony/translation/Tests/Dumper/FileDumperTest.php b/vendor/symfony/translation/Tests/Dumper/FileDumperTest.php index df201461a..20fa918bd 100644 --- a/vendor/symfony/translation/Tests/Dumper/FileDumperTest.php +++ b/vendor/symfony/translation/Tests/Dumper/FileDumperTest.php @@ -32,27 +32,28 @@ class FileDumperTest extends TestCase @unlink($tempDir.'/messages.en.concrete'); } - /** - * @group legacy - */ - public function testDumpBackupsFileIfExisting() + public function testDumpIntl() { $tempDir = sys_get_temp_dir(); - $file = $tempDir.'/messages.en.concrete'; - $backupFile = $file.'~'; - - @touch($file); $catalogue = new MessageCatalogue('en'); - $catalogue->add(['foo' => 'bar']); + $catalogue->add(['foo' => 'bar'], 'd1'); + $catalogue->add(['bar' => 'foo'], 'd1+intl-icu'); + $catalogue->add(['bar' => 'foo'], 'd2+intl-icu'); $dumper = new ConcreteFileDumper(); + @unlink($tempDir.'/d2.en.concrete'); $dumper->dump($catalogue, ['path' => $tempDir]); - $this->assertFileExists($backupFile); + $this->assertStringEqualsFile($tempDir.'/d1.en.concrete', 'foo=bar'); + @unlink($tempDir.'/d1.en.concrete'); - @unlink($file); - @unlink($backupFile); + $this->assertStringEqualsFile($tempDir.'/d1+intl-icu.en.concrete', 'bar=foo'); + @unlink($tempDir.'/d1+intl-icu.en.concrete'); + + $this->assertFileNotExists($tempDir.'/d2.en.concrete'); + $this->assertStringEqualsFile($tempDir.'/d2+intl-icu.en.concrete', 'bar=foo'); + @unlink($tempDir.'/d2+intl-icu.en.concrete'); } public function testDumpCreatesNestedDirectoriesAndFile() @@ -79,7 +80,7 @@ class ConcreteFileDumper extends FileDumper { public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = []) { - return ''; + return http_build_query($messages->all($domain), '', '&'); } protected function getExtension() diff --git a/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php b/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php index e353f85d9..04e3d86be 100644 --- a/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php +++ b/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php @@ -34,6 +34,6 @@ class JsonFileDumperTest extends TestCase $dumper = new JsonFileDumper(); - $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.dump.json', $dumper->formatCatalogue($catalogue, 'messages', ['json_encoding' => \JSON_HEX_QUOT])); + $this->assertStringEqualsFile(__DIR__.'/../fixtures/resources.dump.json', $dumper->formatCatalogue($catalogue, 'messages', ['json_encoding' => JSON_HEX_QUOT])); } } diff --git a/vendor/symfony/translation/Tests/Dumper/PoFileDumperTest.php b/vendor/symfony/translation/Tests/Dumper/PoFileDumperTest.php index 960ec2df6..46df869f8 100644 --- a/vendor/symfony/translation/Tests/Dumper/PoFileDumperTest.php +++ b/vendor/symfony/translation/Tests/Dumper/PoFileDumperTest.php @@ -20,7 +20,26 @@ class PoFileDumperTest extends TestCase public function testFormatCatalogue() { $catalogue = new MessageCatalogue('en'); - $catalogue->add(['foo' => 'bar', 'bar' => 'foo']); + $catalogue->add(['foo' => 'bar', 'bar' => 'foo', 'foo_bar' => 'foobar', 'bar_foo' => 'barfoo']); + $catalogue->setMetadata('foo_bar', [ + 'comments' => [ + 'Comment 1', + 'Comment 2', + ], + 'flags' => [ + 'fuzzy', + 'another', + ], + 'sources' => [ + 'src/file_1', + 'src/file_2:50', + ], + ]); + $catalogue->setMetadata('bar_foo', [ + 'comments' => 'Comment', + 'flags' => 'fuzzy', + 'sources' => 'src/file_1', + ]); $dumper = new PoFileDumper(); diff --git a/vendor/symfony/translation/Tests/Dumper/QtFileDumperTest.php b/vendor/symfony/translation/Tests/Dumper/QtFileDumperTest.php index edfad6005..6c4b55927 100644 --- a/vendor/symfony/translation/Tests/Dumper/QtFileDumperTest.php +++ b/vendor/symfony/translation/Tests/Dumper/QtFileDumperTest.php @@ -20,7 +20,26 @@ class QtFileDumperTest extends TestCase public function testFormatCatalogue() { $catalogue = new MessageCatalogue('en'); - $catalogue->add(['foo' => 'bar'], 'resources'); + $catalogue->add(['foo' => 'bar', 'foo_bar' => 'foobar', 'bar_foo' => 'barfoo'], 'resources'); + $catalogue->setMetadata('foo_bar', [ + 'comments' => [ + 'Comment 1', + 'Comment 2', + ], + 'flags' => [ + 'fuzzy', + 'another', + ], + 'sources' => [ + 'src/file_1', + 'src/file_2:50', + ], + ], 'resources'); + $catalogue->setMetadata('bar_foo', [ + 'comments' => 'Comment', + 'flags' => 'fuzzy', + 'sources' => 'src/file_1', + ], 'resources'); $dumper = new QtFileDumper(); diff --git a/vendor/symfony/translation/Tests/Dumper/XliffFileDumperTest.php b/vendor/symfony/translation/Tests/Dumper/XliffFileDumperTest.php index c634a2793..6377132f7 100644 --- a/vendor/symfony/translation/Tests/Dumper/XliffFileDumperTest.php +++ b/vendor/symfony/translation/Tests/Dumper/XliffFileDumperTest.php @@ -54,6 +54,21 @@ class XliffFileDumperTest extends TestCase ); } + public function testFormatIcuCatalogueXliff2() + { + $catalogue = new MessageCatalogue('en_US'); + $catalogue->add([ + 'foo' => 'bar', + ], 'messages'.MessageCatalogue::INTL_DOMAIN_SUFFIX); + + $dumper = new XliffFileDumper(); + + $this->assertStringEqualsFile( + __DIR__.'/../fixtures/resources-2.0+intl-icu.xlf', + $dumper->formatCatalogue($catalogue, 'messages'.MessageCatalogue::INTL_DOMAIN_SUFFIX, ['default_locale' => 'fr_FR', 'xliff_version' => '2.0']) + ); + } + public function testFormatCatalogueWithCustomToolInfo() { $options = [ diff --git a/vendor/symfony/translation/Tests/Extractor/PhpExtractorTest.php b/vendor/symfony/translation/Tests/Extractor/PhpExtractorTest.php index 7cde10808..a6d7c5001 100644 --- a/vendor/symfony/translation/Tests/Extractor/PhpExtractorTest.php +++ b/vendor/symfony/translation/Tests/Extractor/PhpExtractorTest.php @@ -69,6 +69,10 @@ EOF; $actualCatalogue = $catalogue->all(); $this->assertEquals($expectedCatalogue, $actualCatalogue); + + $filename = str_replace(\DIRECTORY_SEPARATOR, '/', __DIR__).'/../fixtures/extractor/translation.html.php'; + $this->assertEquals(['sources' => [$filename.':2']], $catalogue->getMetadata('single-quoted key')); + $this->assertEquals(['sources' => [$filename.':43']], $catalogue->getMetadata('other-domain-test-no-params-short-array', 'not_messages')); } public function resourcesProvider() diff --git a/vendor/symfony/translation/Tests/Formatter/IntlFormatterTest.php b/vendor/symfony/translation/Tests/Formatter/IntlFormatterTest.php new file mode 100644 index 000000000..37d982cf2 --- /dev/null +++ b/vendor/symfony/translation/Tests/Formatter/IntlFormatterTest.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Tests\Formatter; + +use Symfony\Component\Translation\Exception\InvalidArgumentException; +use Symfony\Component\Translation\Formatter\IntlFormatter; +use Symfony\Component\Translation\Formatter\IntlFormatterInterface; + +/** + * @requires extension intl + */ +class IntlFormatterTest extends \PHPUnit\Framework\TestCase +{ + /** + * @dataProvider provideDataForFormat + */ + public function testFormat($expected, $message, $arguments) + { + $this->assertEquals($expected, trim((new IntlFormatter())->formatIntl($message, 'en', $arguments))); + } + + public function testInvalidFormat() + { + $this->expectException(InvalidArgumentException::class); + (new IntlFormatter())->formatIntl('{foo', 'en', [2]); + } + + public function testFormatWithNamedArguments() + { + if (version_compare(INTL_ICU_VERSION, '4.8', '<')) { + $this->markTestSkipped('Format with named arguments can only be run with ICU 4.8 or higher and PHP >= 5.5'); + } + + $chooseMessage = <<<'_MSG_' +{gender_of_host, select, + female {{num_guests, plural, offset:1 + =0 {{host} does not give a party.} + =1 {{host} invites {guest} to her party.} + =2 {{host} invites {guest} and one other person to her party.} + other {{host} invites {guest} as one of the # people invited to her party.}}} + male {{num_guests, plural, offset:1 + =0 {{host} does not give a party.} + =1 {{host} invites {guest} to his party.} + =2 {{host} invites {guest} and one other person to his party.} + other {{host} invites {guest} as one of the # people invited to his party.}}} + other {{num_guests, plural, offset:1 + =0 {{host} does not give a party.} + =1 {{host} invites {guest} to their party.} + =2 {{host} invites {guest} and one other person to their party.} + other {{host} invites {guest} as one of the # people invited to their party.}}}} +_MSG_; + + $message = (new IntlFormatter())->formatIntl($chooseMessage, 'en', [ + 'gender_of_host' => 'male', + 'num_guests' => 10, + 'host' => 'Fabien', + 'guest' => 'Guilherme', + ]); + + $this->assertEquals('Fabien invites Guilherme as one of the 9 people invited to his party.', $message); + } + + public function provideDataForFormat() + { + return [ + [ + 'There is one apple', + 'There is one apple', + [], + ], + [ + '4,560 monkeys on 123 trees make 37.073 monkeys per tree', + '{0,number,integer} monkeys on {1,number,integer} trees make {2,number} monkeys per tree', + [4560, 123, 4560 / 123], + ], + [ + '', + '', + [], + ], + ]; + } + + public function testPercentsAndBracketsAreTrimmed() + { + $formatter = new IntlFormatter(); + $this->assertInstanceof(IntlFormatterInterface::class, $formatter); + $this->assertSame('Hello Fab', $formatter->formatIntl('Hello {name}', 'en', ['name' => 'Fab'])); + $this->assertSame('Hello Fab', $formatter->formatIntl('Hello {name}', 'en', ['%name%' => 'Fab'])); + $this->assertSame('Hello Fab', $formatter->formatIntl('Hello {name}', 'en', ['{{ name }}' => 'Fab'])); + } +} diff --git a/vendor/symfony/translation/Tests/Formatter/MessageFormatterTest.php b/vendor/symfony/translation/Tests/Formatter/MessageFormatterTest.php index 17b815d30..232bcf904 100644 --- a/vendor/symfony/translation/Tests/Formatter/MessageFormatterTest.php +++ b/vendor/symfony/translation/Tests/Formatter/MessageFormatterTest.php @@ -26,6 +26,7 @@ class MessageFormatterTest extends TestCase /** * @dataProvider getTransChoiceMessages + * @group legacy */ public function testFormatPlural($expected, $message, $number, $parameters) { diff --git a/vendor/symfony/translation/Tests/IdentityTranslatorTest.php b/vendor/symfony/translation/Tests/IdentityTranslatorTest.php index a5c63df98..a630a7a3c 100644 --- a/vendor/symfony/translation/Tests/IdentityTranslatorTest.php +++ b/vendor/symfony/translation/Tests/IdentityTranslatorTest.php @@ -11,102 +11,29 @@ namespace Symfony\Component\Translation\Tests; -use PHPUnit\Framework\TestCase; -use Symfony\Component\Intl\Util\IntlTestHelper; use Symfony\Component\Translation\IdentityTranslator; +use Symfony\Contracts\Translation\Test\TranslatorTest; -class IdentityTranslatorTest extends TestCase +class IdentityTranslatorTest extends TranslatorTest { private $defaultLocale; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->defaultLocale = \Locale::getDefault(); } - protected function tearDown() + protected function tearDown(): void { parent::tearDown(); \Locale::setDefault($this->defaultLocale); } - /** - * @dataProvider getTransTests - */ - public function testTrans($expected, $id, $parameters) + public function getTranslator() { - $translator = new IdentityTranslator(); - - $this->assertEquals($expected, $translator->trans($id, $parameters)); - } - - /** - * @dataProvider getTransChoiceTests - */ - public function testTransChoiceWithExplicitLocale($expected, $id, $number, $parameters) - { - $translator = new IdentityTranslator(); - $translator->setLocale('en'); - - $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters)); - } - - /** - * @dataProvider getTransChoiceTests - */ - public function testTransChoiceWithDefaultLocale($expected, $id, $number, $parameters) - { - \Locale::setDefault('en'); - - $translator = new IdentityTranslator(); - - $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters)); - } - - public function testGetSetLocale() - { - $translator = new IdentityTranslator(); - $translator->setLocale('en'); - - $this->assertEquals('en', $translator->getLocale()); - } - - public function testGetLocaleReturnsDefaultLocaleIfNotSet() - { - // in order to test with "pt_BR" - IntlTestHelper::requireFullIntl($this, false); - - $translator = new IdentityTranslator(); - - \Locale::setDefault('en'); - $this->assertEquals('en', $translator->getLocale()); - - \Locale::setDefault('pt_BR'); - $this->assertEquals('pt_BR', $translator->getLocale()); - } - - public function getTransTests() - { - return [ - ['Symfony is great!', 'Symfony is great!', []], - ['Symfony is awesome!', 'Symfony is %what%!', ['%what%' => 'awesome']], - ]; - } - - public function getTransChoiceTests() - { - return [ - ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0, ['%count%' => 0]], - ['There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1, ['%count%' => 1]], - ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10, ['%count%' => 10]], - ['There are 0 apples', 'There is 1 apple|There are %count% apples', 0, ['%count%' => 0]], - ['There is 1 apple', 'There is 1 apple|There are %count% apples', 1, ['%count%' => 1]], - ['There are 10 apples', 'There is 1 apple|There are %count% apples', 10, ['%count%' => 10]], - // custom validation messages may be coded with a fixed value - ['There are 2 apples', 'There are 2 apples', 2, ['%count%' => 2]], - ]; + return new IdentityTranslator(); } } diff --git a/vendor/symfony/translation/Tests/IntervalTest.php b/vendor/symfony/translation/Tests/IntervalTest.php index e49a30bf1..ea3e4d8d5 100644 --- a/vendor/symfony/translation/Tests/IntervalTest.php +++ b/vendor/symfony/translation/Tests/IntervalTest.php @@ -14,6 +14,9 @@ namespace Symfony\Component\Translation\Tests; use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\Interval; +/** + * @group legacy + */ class IntervalTest extends TestCase { /** diff --git a/vendor/symfony/translation/Tests/Loader/JsonFileLoaderTest.php b/vendor/symfony/translation/Tests/Loader/JsonFileLoaderTest.php index c5a9ca64d..d264bb16b 100644 --- a/vendor/symfony/translation/Tests/Loader/JsonFileLoaderTest.php +++ b/vendor/symfony/translation/Tests/Loader/JsonFileLoaderTest.php @@ -50,7 +50,7 @@ class JsonFileLoaderTest extends TestCase public function testParseException() { $this->expectException('Symfony\Component\Translation\Exception\InvalidResourceException'); - $this->expectExceptionMessage('Error parsing JSON: Syntax error, malformed JSON'); + $this->expectExceptionMessage('Error parsing JSON - Syntax error, malformed JSON'); $loader = new JsonFileLoader(); $resource = __DIR__.'/../fixtures/malformed.json'; $loader->load($resource, 'en', 'domain1'); diff --git a/vendor/symfony/translation/Tests/Loader/LocalizedTestCase.php b/vendor/symfony/translation/Tests/Loader/LocalizedTestCase.php index 279e9fde5..b4a4a12e2 100644 --- a/vendor/symfony/translation/Tests/Loader/LocalizedTestCase.php +++ b/vendor/symfony/translation/Tests/Loader/LocalizedTestCase.php @@ -15,7 +15,7 @@ use PHPUnit\Framework\TestCase; abstract class LocalizedTestCase extends TestCase { - protected function setUp() + protected function setUp(): void { if (!\extension_loaded('intl')) { $this->markTestSkipped('Extension intl is required.'); diff --git a/vendor/symfony/translation/Tests/Loader/QtFileLoaderTest.php b/vendor/symfony/translation/Tests/Loader/QtFileLoaderTest.php index 47462d6aa..95981c7fe 100644 --- a/vendor/symfony/translation/Tests/Loader/QtFileLoaderTest.php +++ b/vendor/symfony/translation/Tests/Loader/QtFileLoaderTest.php @@ -23,7 +23,11 @@ class QtFileLoaderTest extends TestCase $resource = __DIR__.'/../fixtures/resources.ts'; $catalogue = $loader->load($resource, 'en', 'resources'); - $this->assertEquals(['foo' => 'bar'], $catalogue->all('resources')); + $this->assertEquals([ + 'foo' => 'bar', + 'foo_bar' => 'foobar', + 'bar_foo' => 'barfoo', + ], $catalogue->all('resources')); $this->assertEquals('en', $catalogue->getLocale()); $this->assertEquals([new FileResource($resource)], $catalogue->getResources()); } diff --git a/vendor/symfony/translation/Tests/Loader/XliffFileLoaderTest.php b/vendor/symfony/translation/Tests/Loader/XliffFileLoaderTest.php index dca013b5d..79e51f123 100644 --- a/vendor/symfony/translation/Tests/Loader/XliffFileLoaderTest.php +++ b/vendor/symfony/translation/Tests/Loader/XliffFileLoaderTest.php @@ -49,17 +49,13 @@ class XliffFileLoaderTest extends TestCase public function testLoadWithExternalEntitiesDisabled() { - if (\LIBXML_VERSION < 20900) { - $disableEntities = libxml_disable_entity_loader(true); - } + $disableEntities = libxml_disable_entity_loader(true); $loader = new XliffFileLoader(); $resource = __DIR__.'/../fixtures/resources.xlf'; $catalogue = $loader->load($resource, 'en', 'domain1'); - if (\LIBXML_VERSION < 20900) { - libxml_disable_entity_loader($disableEntities); - } + libxml_disable_entity_loader($disableEntities); $this->assertEquals('en', $catalogue->getLocale()); $this->assertEquals([new FileResource($resource)], $catalogue->getResources()); @@ -88,7 +84,17 @@ class XliffFileLoaderTest extends TestCase $this->assertEquals(utf8_decode('föö'), $catalogue->get('bar', 'domain1')); $this->assertEquals(utf8_decode('bär'), $catalogue->get('foo', 'domain1')); - $this->assertEquals(['notes' => [['content' => utf8_decode('bäz')]], 'id' => '1'], $catalogue->getMetadata('foo', 'domain1')); + $this->assertEquals( + [ + 'source' => 'foo', + 'notes' => [['content' => utf8_decode('bäz')]], + 'id' => '1', + 'file' => [ + 'original' => 'file.ext', + ], + ], + $catalogue->getMetadata('foo', 'domain1') + ); } public function testTargetAttributesAreStoredCorrectly() @@ -154,11 +160,44 @@ class XliffFileLoaderTest extends TestCase $loader = new XliffFileLoader(); $catalogue = $loader->load(__DIR__.'/../fixtures/withnote.xlf', 'en', 'domain1'); - $this->assertEquals(['notes' => [['priority' => 1, 'content' => 'foo']], 'id' => '1'], $catalogue->getMetadata('foo', 'domain1')); + $this->assertEquals( + [ + 'source' => 'foo', + 'notes' => [['priority' => 1, 'content' => 'foo']], + 'id' => '1', + 'file' => [ + 'original' => 'file.ext', + ], + ], + $catalogue->getMetadata('foo', 'domain1') + ); // message without target - $this->assertEquals(['notes' => [['content' => 'bar', 'from' => 'foo']], 'id' => '2'], $catalogue->getMetadata('extra', 'domain1')); + $this->assertEquals( + [ + 'source' => 'extrasource', + 'notes' => [['content' => 'bar', 'from' => 'foo']], + 'id' => '2', + 'file' => [ + 'original' => 'file.ext', + ], + ], + $catalogue->getMetadata('extra', 'domain1') + ); // message with empty target - $this->assertEquals(['notes' => [['content' => 'baz'], ['priority' => 2, 'from' => 'bar', 'content' => 'qux']], 'id' => '123'], $catalogue->getMetadata('key', 'domain1')); + $this->assertEquals( + [ + 'source' => 'key', + 'notes' => [ + ['content' => 'baz'], + ['priority' => 2, 'from' => 'bar', 'content' => 'qux'], + ], + 'id' => '123', + 'file' => [ + 'original' => 'file.ext', + ], + ], + $catalogue->getMetadata('key', 'domain1') + ); } public function testLoadVersion2() @@ -247,4 +286,32 @@ class XliffFileLoaderTest extends TestCase $this->assertSame('processed', $metadata['notes'][0]['category']); $this->assertSame('true', $metadata['notes'][0]['content']); } + + public function testLoadWithMultipleFileNodes() + { + $loader = new XliffFileLoader(); + $catalogue = $loader->load(__DIR__.'/../fixtures/resources-multi-files.xlf', 'en', 'domain1'); + + $this->assertEquals( + [ + 'source' => 'foo', + 'id' => '1', + 'file' => [ + 'original' => 'file.ext', + ], + ], + $catalogue->getMetadata('foo', 'domain1') + ); + $this->assertEquals( + [ + 'source' => 'test', + 'notes' => [['content' => 'note']], + 'id' => '4', + 'file' => [ + 'original' => 'otherfile.ext', + ], + ], + $catalogue->getMetadata('test', 'domain1') + ); + } } diff --git a/vendor/symfony/translation/Tests/LoggingTranslatorTest.php b/vendor/symfony/translation/Tests/LoggingTranslatorTest.php index 1d3f065a5..450e060aa 100644 --- a/vendor/symfony/translation/Tests/LoggingTranslatorTest.php +++ b/vendor/symfony/translation/Tests/LoggingTranslatorTest.php @@ -21,17 +21,19 @@ class LoggingTranslatorTest extends TestCase public function testTransWithNoTranslationIsLogged() { $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); - $logger->expects($this->exactly(2)) + $logger->expects($this->exactly(1)) ->method('warning') ->with('Translation not found.') ; $translator = new Translator('ar'); $loggableTranslator = new LoggingTranslator($translator, $logger); - $loggableTranslator->transChoice('some_message2', 10, ['%count%' => 10]); $loggableTranslator->trans('bar'); } + /** + * @group legacy + */ public function testTransChoiceFallbackIsLogged() { $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); @@ -47,4 +49,20 @@ class LoggingTranslatorTest extends TestCase $loggableTranslator = new LoggingTranslator($translator, $logger); $loggableTranslator->transChoice('some_message2', 10, ['%count%' => 10]); } + + /** + * @group legacy + */ + public function testTransChoiceWithNoTranslationIsLogged() + { + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $logger->expects($this->exactly(1)) + ->method('warning') + ->with('Translation not found.') + ; + + $translator = new Translator('ar'); + $loggableTranslator = new LoggingTranslator($translator, $logger); + $loggableTranslator->transChoice('some_message2', 10, ['%count%' => 10]); + } } diff --git a/vendor/symfony/translation/Tests/MessageCatalogueTest.php b/vendor/symfony/translation/Tests/MessageCatalogueTest.php index b78dbf42e..34f26047a 100644 --- a/vendor/symfony/translation/Tests/MessageCatalogueTest.php +++ b/vendor/symfony/translation/Tests/MessageCatalogueTest.php @@ -25,9 +25,9 @@ class MessageCatalogueTest extends TestCase public function testGetDomains() { - $catalogue = new MessageCatalogue('en', ['domain1' => [], 'domain2' => []]); + $catalogue = new MessageCatalogue('en', ['domain1' => [], 'domain2' => [], 'domain2+intl-icu' => [], 'domain3+intl-icu' => []]); - $this->assertEquals(['domain1', 'domain2'], $catalogue->getDomains()); + $this->assertEquals(['domain1', 'domain2', 'domain3'], $catalogue->getDomains()); } public function testAll() @@ -37,24 +37,43 @@ class MessageCatalogueTest extends TestCase $this->assertEquals(['foo' => 'foo'], $catalogue->all('domain1')); $this->assertEquals([], $catalogue->all('domain88')); $this->assertEquals($messages, $catalogue->all()); + + $messages = ['domain1+intl-icu' => ['foo' => 'bar']] + $messages + [ + 'domain2+intl-icu' => ['bar' => 'foo'], + 'domain3+intl-icu' => ['biz' => 'biz'], + ]; + $catalogue = new MessageCatalogue('en', $messages); + + $this->assertEquals(['foo' => 'bar'], $catalogue->all('domain1')); + $this->assertEquals(['bar' => 'foo'], $catalogue->all('domain2')); + $this->assertEquals(['biz' => 'biz'], $catalogue->all('domain3')); + + $messages = [ + 'domain1' => ['foo' => 'bar'], + 'domain2' => ['bar' => 'foo'], + 'domain3' => ['biz' => 'biz'], + ]; + $this->assertEquals($messages, $catalogue->all()); } public function testHas() { - $catalogue = new MessageCatalogue('en', ['domain1' => ['foo' => 'foo'], 'domain2' => ['bar' => 'bar']]); + $catalogue = new MessageCatalogue('en', ['domain1' => ['foo' => 'foo'], 'domain2+intl-icu' => ['bar' => 'bar']]); $this->assertTrue($catalogue->has('foo', 'domain1')); + $this->assertTrue($catalogue->has('bar', 'domain2')); $this->assertFalse($catalogue->has('bar', 'domain1')); $this->assertFalse($catalogue->has('foo', 'domain88')); } public function testGetSet() { - $catalogue = new MessageCatalogue('en', ['domain1' => ['foo' => 'foo'], 'domain2' => ['bar' => 'bar']]); + $catalogue = new MessageCatalogue('en', ['domain1' => ['foo' => 'foo'], 'domain2' => ['bar' => 'bar'], 'domain2+intl-icu' => ['bar' => 'foo']]); $catalogue->set('foo1', 'foo1', 'domain1'); $this->assertEquals('foo', $catalogue->get('foo', 'domain1')); $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1')); + $this->assertEquals('foo', $catalogue->get('bar', 'domain2')); } public function testAdd() @@ -75,7 +94,7 @@ class MessageCatalogueTest extends TestCase public function testReplace() { - $catalogue = new MessageCatalogue('en', ['domain1' => ['foo' => 'foo'], 'domain2' => ['bar' => 'bar']]); + $catalogue = new MessageCatalogue('en', ['domain1' => ['foo' => 'foo'], 'domain1+intl-icu' => ['bar' => 'bar']]); $catalogue->replace($messages = ['foo1' => 'foo1'], 'domain1'); $this->assertEquals($messages, $catalogue->all('domain1')); @@ -89,16 +108,18 @@ class MessageCatalogueTest extends TestCase $r1 = $this->getMockBuilder('Symfony\Component\Config\Resource\ResourceInterface')->getMock(); $r1->expects($this->any())->method('__toString')->willReturn('r1'); - $catalogue = new MessageCatalogue('en', ['domain1' => ['foo' => 'foo'], 'domain2' => ['bar' => 'bar']]); + $catalogue = new MessageCatalogue('en', ['domain1' => ['foo' => 'foo']]); $catalogue->addResource($r); - $catalogue1 = new MessageCatalogue('en', ['domain1' => ['foo1' => 'foo1']]); + $catalogue1 = new MessageCatalogue('en', ['domain1' => ['foo1' => 'foo1'], 'domain2+intl-icu' => ['bar' => 'bar']]); $catalogue1->addResource($r1); $catalogue->addCatalogue($catalogue1); $this->assertEquals('foo', $catalogue->get('foo', 'domain1')); $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1')); + $this->assertEquals('bar', $catalogue->get('bar', 'domain2')); + $this->assertEquals('bar', $catalogue->get('bar', 'domain2+intl-icu')); $this->assertEquals([$r, $r1], $catalogue->getResources()); } diff --git a/vendor/symfony/translation/Tests/MessageSelectorTest.php b/vendor/symfony/translation/Tests/MessageSelectorTest.php index abb1d4847..20609ddda 100644 --- a/vendor/symfony/translation/Tests/MessageSelectorTest.php +++ b/vendor/symfony/translation/Tests/MessageSelectorTest.php @@ -14,6 +14,9 @@ namespace Symfony\Component\Translation\Tests; use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\MessageSelector; +/** + * @group legacy + */ class MessageSelectorTest extends TestCase { /** diff --git a/vendor/symfony/translation/Tests/PluralizationRulesTest.php b/vendor/symfony/translation/Tests/PluralizationRulesTest.php index d93fab804..696c92b2d 100644 --- a/vendor/symfony/translation/Tests/PluralizationRulesTest.php +++ b/vendor/symfony/translation/Tests/PluralizationRulesTest.php @@ -26,6 +26,8 @@ use Symfony\Component\Translation\PluralizationRules; * The goal to cover all languages is to far fetched so this test case is smaller. * * @author Clemens Tolboom clemens@build2be.nl + * + * @group legacy */ class PluralizationRulesTest extends TestCase { @@ -100,9 +102,9 @@ class PluralizationRulesTest extends TestCase foreach ($matrix as $langCode => $data) { $indexes = array_flip($data); if ($expectSuccess) { - $this->assertCount((int) $nplural, $indexes, "Langcode '$langCode' has '$nplural' plural forms."); + $this->assertEquals($nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms."); } else { - $this->assertNotCount((int) $nplural, $indexes, "Langcode '$langCode' has '$nplural' plural forms."); + $this->assertNotEquals((int) $nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms."); } } } diff --git a/vendor/symfony/translation/Tests/TranslatorCacheTest.php b/vendor/symfony/translation/Tests/TranslatorCacheTest.php index 6b23a9f1e..ae5c75ba8 100644 --- a/vendor/symfony/translation/Tests/TranslatorCacheTest.php +++ b/vendor/symfony/translation/Tests/TranslatorCacheTest.php @@ -23,13 +23,13 @@ class TranslatorCacheTest extends TestCase { protected $tmpDir; - protected function setUp() + protected function setUp(): void { - $this->tmpDir = sys_get_temp_dir().'/sf2_translation'; + $this->tmpDir = sys_get_temp_dir().'/sf_translation'; $this->deleteTmpDir(); } - protected function tearDown() + protected function tearDown(): void { $this->deleteTmpDir(); } @@ -67,13 +67,17 @@ class TranslatorCacheTest extends TestCase $translator = new Translator($locale, null, $this->tmpDir, $debug); $translator->addLoader($format, new ArrayLoader()); $translator->addResource($format, [$msgid => 'OK'], $locale); + $translator->addResource($format, [$msgid.'+intl' => 'OK'], $locale, 'messages+intl-icu'); $translator->trans($msgid); + $translator->trans($msgid.'+intl', [], 'messages+intl-icu'); // Try again and see we get a valid result whilst no loader can be used $translator = new Translator($locale, null, $this->tmpDir, $debug); $translator->addLoader($format, $this->createFailingLoader()); $translator->addResource($format, [$msgid => 'OK'], $locale); + $translator->addResource($format, [$msgid.'+intl' => 'OK'], $locale, 'messages+intl-icu'); $this->assertEquals('OK', $translator->trans($msgid), '-> caching does not work in '.($debug ? 'debug' : 'production')); + $this->assertEquals('OK', $translator->trans($msgid.'+intl', [], 'messages+intl-icu')); } public function testCatalogueIsReloadedWhenResourcesAreNoLongerFresh() @@ -213,6 +217,7 @@ class TranslatorCacheTest extends TestCase $translator->addResource('array', ['foo' => 'foo (a)'], 'a'); $translator->addResource('array', ['foo' => 'foo (b)'], 'b'); $translator->addResource('array', ['bar' => 'bar (b)'], 'b'); + $translator->addResource('array', ['baz' => 'baz (b)'], 'b', 'messages+intl-icu'); $catalogue = $translator->getCatalogue('a'); $this->assertFalse($catalogue->defines('bar')); // Sure, the "a" catalogue does not contain that message. @@ -231,12 +236,14 @@ class TranslatorCacheTest extends TestCase $translator->addResource('array', ['foo' => 'foo (a)'], 'a'); $translator->addResource('array', ['foo' => 'foo (b)'], 'b'); $translator->addResource('array', ['bar' => 'bar (b)'], 'b'); + $translator->addResource('array', ['baz' => 'baz (b)'], 'b', 'messages+intl-icu'); $catalogue = $translator->getCatalogue('a'); $this->assertFalse($catalogue->defines('bar')); $fallback = $catalogue->getFallbackCatalogue(); $this->assertTrue($fallback->defines('foo')); + $this->assertTrue($fallback->defines('baz', 'messages+intl-icu')); } public function testRefreshCacheWhenResourcesAreNoLongerFresh() @@ -262,6 +269,22 @@ class TranslatorCacheTest extends TestCase $translator->trans('foo'); } + public function testCachedCatalogueIsReDumpedWhenCacheVaryChange() + { + $translator = new Translator('a', null, $this->tmpDir, false, []); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', ['foo' => 'bar'], 'a', 'messages'); + + // Cached catalogue is dumped + $this->assertSame('bar', $translator->trans('foo', [], 'messages', 'a')); + + $translator = new Translator('a', null, $this->tmpDir, false, ['vary']); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', ['foo' => 'ccc'], 'a', 'messages'); + + $this->assertSame('ccc', $translator->trans('foo', [], 'messages', 'a')); + } + protected function getCatalogue($locale, $messages, $resources = []) { $catalogue = new MessageCatalogue($locale); diff --git a/vendor/symfony/translation/Tests/TranslatorTest.php b/vendor/symfony/translation/Tests/TranslatorTest.php index cb422cf00..d7c5b45e0 100644 --- a/vendor/symfony/translation/Tests/TranslatorTest.php +++ b/vendor/symfony/translation/Tests/TranslatorTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Translation\Tests; use PHPUnit\Framework\TestCase; -use Symfony\Component\Translation\Exception\RuntimeException; use Symfony\Component\Translation\Loader\ArrayLoader; use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Translation\Translator; @@ -235,6 +234,42 @@ class TranslatorTest extends TestCase $this->assertEquals('bar', $translator->trans('foo', [], 'resources')); } + public function testTransWithIcuFallbackLocale() + { + $translator = new Translator('en_GB'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', ['foo' => 'foofoo'], 'en_GB'); + $translator->addResource('array', ['bar' => 'foobar'], 'en_001'); + $translator->addResource('array', ['baz' => 'foobaz'], 'en'); + $this->assertSame('foofoo', $translator->trans('foo')); + $this->assertSame('foobar', $translator->trans('bar')); + $this->assertSame('foobaz', $translator->trans('baz')); + } + + public function testTransWithIcuVariantFallbackLocale() + { + $translator = new Translator('en_GB_scouse'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', ['foo' => 'foofoo'], 'en_GB_scouse'); + $translator->addResource('array', ['bar' => 'foobar'], 'en_GB'); + $translator->addResource('array', ['baz' => 'foobaz'], 'en_001'); + $translator->addResource('array', ['qux' => 'fooqux'], 'en'); + $this->assertSame('foofoo', $translator->trans('foo')); + $this->assertSame('foobar', $translator->trans('bar')); + $this->assertSame('foobaz', $translator->trans('baz')); + $this->assertSame('fooqux', $translator->trans('qux')); + } + + public function testTransWithIcuRootFallbackLocale() + { + $translator = new Translator('az_Cyrl'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', ['foo' => 'foofoo'], 'az_Cyrl'); + $translator->addResource('array', ['bar' => 'foobar'], 'az'); + $this->assertSame('foofoo', $translator->trans('foo')); + $this->assertSame('bar', $translator->trans('bar')); + } + /** * @dataProvider getFallbackLocales */ @@ -319,12 +354,12 @@ class TranslatorTest extends TestCase $resources = $translator->getCatalogue('en')->getResources(); $this->assertCount(1, $resources); - $this->assertContainsEquals(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'resources.yml', $resources); + $this->assertContains(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'resources.yml', $resources); $resources = $translator->getCatalogue('en_GB')->getResources(); $this->assertCount(2, $resources); - $this->assertContainsEquals(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'empty.yml', $resources); - $this->assertContainsEquals(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'resources.yml', $resources); + $this->assertContains(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'empty.yml', $resources); + $this->assertContains(__DIR__.\DIRECTORY_SEPARATOR.'fixtures'.\DIRECTORY_SEPARATOR.'resources.yml', $resources); } /** @@ -379,6 +414,7 @@ class TranslatorTest extends TestCase /** * @dataProvider getTransChoiceTests + * @group legacy */ public function testTransChoice($expected, $id, $translation, $number, $parameters, $locale, $domain) { @@ -391,6 +427,7 @@ class TranslatorTest extends TestCase /** * @dataProvider getInvalidLocalesTests + * @group legacy */ public function testTransChoiceInvalidLocale($locale) { @@ -404,6 +441,7 @@ class TranslatorTest extends TestCase /** * @dataProvider getValidLocalesTests + * @group legacy */ public function testTransChoiceValidLocale($locale) { @@ -485,7 +523,7 @@ class TranslatorTest extends TestCase ['Il y a 0 pomme', new StringClass('{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples'), '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, [], 'fr', ''], // Override %count% with a custom value - ['Il y a quelques pommes', 'one: There is one apple|more: There are %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 2, ['%count%' => 'quelques'], 'fr', ''], + ['Il y a quelques pommes', 'one: There is one apple|more: There are %count% apples', 'one: Il y a %count% pomme|more: Il y a quelques pommes', 2, ['%count%' => 'quelques'], 'fr', ''], ]; } @@ -523,6 +561,24 @@ class TranslatorTest extends TestCase ]; } + /** + * @requires extension intl + */ + public function testIntlFormattedDomain() + { + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + + $translator->addResource('array', ['some_message' => 'Hello %name%'], 'en'); + $this->assertSame('Hello Bob', $translator->trans('some_message', ['%name%' => 'Bob'])); + + $translator->addResource('array', ['some_message' => 'Hi {name}'], 'en', 'messages+intl-icu'); + $this->assertSame('Hi Bob', $translator->trans('some_message', ['%name%' => 'Bob'])); + } + + /** + * @group legacy + */ public function testTransChoiceFallback() { $translator = new Translator('ru'); @@ -533,6 +589,9 @@ class TranslatorTest extends TestCase $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, ['%count%' => 10])); } + /** + * @group legacy + */ public function testTransChoiceFallbackBis() { $translator = new Translator('ru'); @@ -543,6 +602,9 @@ class TranslatorTest extends TestCase $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, ['%count%' => 10])); } + /** + * @group legacy + */ public function testTransChoiceFallbackWithNoTranslation() { $translator = new Translator('ru'); @@ -553,16 +615,6 @@ class TranslatorTest extends TestCase // unchanged if it can't be found $this->assertEquals('some_message2', $translator->transChoice('some_message2', 10, ['%count%' => 10])); } - - public function testMissingLoaderForResourceError() - { - $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('No loader is registered for the "twig" format when loading the "messages.en.twig" resource.'); - - $translator = new Translator('en'); - $translator->addResource('twig', 'messages.en.twig', 'en'); - $translator->getCatalogue('en'); - } } class StringClass diff --git a/vendor/symfony/translation/Tests/Writer/TranslationWriterTest.php b/vendor/symfony/translation/Tests/Writer/TranslationWriterTest.php index dbcc14e6e..d3b6754d3 100644 --- a/vendor/symfony/translation/Tests/Writer/TranslationWriterTest.php +++ b/vendor/symfony/translation/Tests/Writer/TranslationWriterTest.php @@ -18,22 +18,6 @@ use Symfony\Component\Translation\Writer\TranslationWriter; class TranslationWriterTest extends TestCase { - /** - * @group legacy - * @expectedDeprecation The "Symfony\Component\Translation\Writer\TranslationWriter::writeTranslations()" method is deprecated since Symfony 3.4 and will be removed in 4.0. Use write() instead. - */ - public function testWriteTranslations() - { - $dumper = $this->getMockBuilder('Symfony\Component\Translation\Dumper\DumperInterface')->getMock(); - $dumper - ->expects($this->once()) - ->method('dump'); - - $writer = new TranslationWriter(); - $writer->addDumper('test', $dumper); - $writer->writeTranslations(new MessageCatalogue('en'), 'test'); - } - public function testWrite() { $dumper = $this->getMockBuilder('Symfony\Component\Translation\Dumper\DumperInterface')->getMock(); @@ -43,9 +27,12 @@ class TranslationWriterTest extends TestCase $writer = new TranslationWriter(); $writer->addDumper('test', $dumper); - $writer->write(new MessageCatalogue([]), 'test'); + $writer->write(new MessageCatalogue('en'), 'test'); } + /** + * @group legacy + */ public function testDisableBackup() { $nonBackupDumper = new NonBackupDumper(); diff --git a/vendor/symfony/translation/Tests/fixtures/resources-2.0+intl-icu.xlf b/vendor/symfony/translation/Tests/fixtures/resources-2.0+intl-icu.xlf new file mode 100644 index 000000000..6294f162f --- /dev/null +++ b/vendor/symfony/translation/Tests/fixtures/resources-2.0+intl-icu.xlf @@ -0,0 +1,11 @@ + + + + + + foo + bar + + + + diff --git a/vendor/symfony/translation/Tests/fixtures/resources-2.0-clean.xlf b/vendor/symfony/translation/Tests/fixtures/resources-2.0-clean.xlf index 06047dde5..efa69b27f 100644 --- a/vendor/symfony/translation/Tests/fixtures/resources-2.0-clean.xlf +++ b/vendor/symfony/translation/Tests/fixtures/resources-2.0-clean.xlf @@ -1,19 +1,19 @@ - + foo bar - + key - + key.with.cdata & ]]> diff --git a/vendor/symfony/translation/Tests/fixtures/resources-multi-files.xlf b/vendor/symfony/translation/Tests/fixtures/resources-multi-files.xlf new file mode 100644 index 000000000..5f451508b --- /dev/null +++ b/vendor/symfony/translation/Tests/fixtures/resources-multi-files.xlf @@ -0,0 +1,27 @@ + + + + + + foo + bar + + + + + + + extra + + + key + + + + test + with + note + + + + diff --git a/vendor/symfony/translation/Tests/fixtures/resources-notes-meta.xlf b/vendor/symfony/translation/Tests/fixtures/resources-notes-meta.xlf index e9995fa84..7d5bbd40f 100644 --- a/vendor/symfony/translation/Tests/fixtures/resources-notes-meta.xlf +++ b/vendor/symfony/translation/Tests/fixtures/resources-notes-meta.xlf @@ -1,7 +1,7 @@ - + new true @@ -12,7 +12,7 @@ bar - + x_content Fuzzy diff --git a/vendor/symfony/translation/Tests/fixtures/resources.po b/vendor/symfony/translation/Tests/fixtures/resources.po index a20e61982..68e0f2d7e 100644 --- a/vendor/symfony/translation/Tests/fixtures/resources.po +++ b/vendor/symfony/translation/Tests/fixtures/resources.po @@ -9,3 +9,16 @@ msgstr "bar" msgid "bar" msgstr "foo" + +# Comment 1 +# Comment 2 +#, fuzzy,another +#: src/file_1 src/file_2:50 +msgid "foo_bar" +msgstr "foobar" + +# Comment +#, fuzzy +#: src/file_1 +msgid "bar_foo" +msgstr "barfoo" diff --git a/vendor/symfony/translation/Tests/fixtures/resources.ts b/vendor/symfony/translation/Tests/fixtures/resources.ts index 40e18522c..29e6a6fad 100644 --- a/vendor/symfony/translation/Tests/fixtures/resources.ts +++ b/vendor/symfony/translation/Tests/fixtures/resources.ts @@ -6,5 +6,16 @@ foo bar + + + + foo_bar + foobar + + + + bar_foo + barfoo + diff --git a/vendor/symfony/translation/Tests/fixtures/withnote.xlf b/vendor/symfony/translation/Tests/fixtures/withnote.xlf index c045e21e2..f98cf7f97 100644 --- a/vendor/symfony/translation/Tests/fixtures/withnote.xlf +++ b/vendor/symfony/translation/Tests/fixtures/withnote.xlf @@ -7,8 +7,8 @@ bar foo - - extra + + extrasource bar diff --git a/vendor/symfony/translation/Translator.php b/vendor/symfony/translation/Translator.php index 06c0aa2e2..2faf3ac96 100644 --- a/vendor/symfony/translation/Translator.php +++ b/vendor/symfony/translation/Translator.php @@ -19,14 +19,17 @@ use Symfony\Component\Translation\Exception\LogicException; use Symfony\Component\Translation\Exception\NotFoundResourceException; use Symfony\Component\Translation\Exception\RuntimeException; use Symfony\Component\Translation\Formatter\ChoiceMessageFormatterInterface; +use Symfony\Component\Translation\Formatter\IntlFormatterInterface; use Symfony\Component\Translation\Formatter\MessageFormatter; use Symfony\Component\Translation\Formatter\MessageFormatterInterface; use Symfony\Component\Translation\Loader\LoaderInterface; +use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; /** * @author Fabien Potencier */ -class Translator implements TranslatorInterface, TranslatorBagInterface +class Translator implements LegacyTranslatorInterface, TranslatorInterface, TranslatorBagInterface { /** * @var MessageCatalogueInterface[] @@ -68,33 +71,36 @@ class Translator implements TranslatorInterface, TranslatorBagInterface */ private $debug; + private $cacheVary; + /** * @var ConfigCacheFactoryInterface|null */ private $configCacheFactory; /** - * @param string $locale The locale - * @param MessageFormatterInterface|null $formatter The message formatter - * @param string|null $cacheDir The directory to use for the cache - * @param bool $debug Use cache in debug mode ? - * + * @var array|null + */ + private $parentLocales; + + private $hasIntlFormatter; + + /** * @throws InvalidArgumentException If a locale contains invalid characters */ - public function __construct($locale, $formatter = null, $cacheDir = null, $debug = false) + public function __construct(?string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false, array $cacheVary = []) { $this->setLocale($locale); - if ($formatter instanceof MessageSelector) { - $formatter = new MessageFormatter($formatter); - @trigger_error(sprintf('Passing a "%s" instance into the "%s()" method as a second argument is deprecated since Symfony 3.4 and will be removed in 4.0. Inject a "%s" implementation instead.', MessageSelector::class, __METHOD__, MessageFormatterInterface::class), \E_USER_DEPRECATED); - } elseif (null === $formatter) { + if (null === $formatter) { $formatter = new MessageFormatter(); } $this->formatter = $formatter; $this->cacheDir = $cacheDir; $this->debug = $debug; + $this->cacheVary = $cacheVary; + $this->hasIntlFormatter = $formatter instanceof IntlFormatterInterface; } public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory) @@ -173,12 +179,14 @@ class Translator implements TranslatorInterface, TranslatorBagInterface $this->assertValidLocale($locale); } - $this->fallbackLocales = $locales; + $this->fallbackLocales = $this->cacheVary['fallback_locales'] = $locales; } /** * Gets the fallback locales. * + * @internal since Symfony 4.2 + * * @return array The fallback locales */ public function getFallbackLocales() @@ -195,14 +203,34 @@ class Translator implements TranslatorInterface, TranslatorBagInterface $domain = 'messages'; } - return $this->formatter->format($this->getCatalogue($locale)->get((string) $id, $domain), $locale, $parameters); + $id = (string) $id; + $catalogue = $this->getCatalogue($locale); + $locale = $catalogue->getLocale(); + while (!$catalogue->defines($id, $domain)) { + if ($cat = $catalogue->getFallbackCatalogue()) { + $catalogue = $cat; + $locale = $catalogue->getLocale(); + } else { + break; + } + } + + if ($this->hasIntlFormatter && $catalogue->defines($id, $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)) { + return $this->formatter->formatIntl($catalogue->get($id, $domain), $locale, $parameters); + } + + return $this->formatter->format($catalogue->get($id, $domain), $locale, $parameters); } /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2, use the trans() method instead with a %count% parameter */ public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null) { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the trans() one instead with a "%%count%%" parameter.', __METHOD__), E_USER_DEPRECATED); + if (!$this->formatter instanceof ChoiceMessageFormatterInterface) { throw new LogicException(sprintf('The formatter "%s" does not support plural translations.', \get_class($this->formatter))); } @@ -223,6 +251,10 @@ class Translator implements TranslatorInterface, TranslatorBagInterface } } + if ($this->hasIntlFormatter && $catalogue->defines($id, $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)) { + return $this->formatter->formatIntl($catalogue->get($id, $domain), $locale, ['%count%' => $number] + $parameters); + } + return $this->formatter->choiceFormat($catalogue->get($id, $domain), $number, $locale, $parameters); } @@ -283,10 +315,7 @@ class Translator implements TranslatorInterface, TranslatorBagInterface $this->loadFallbackCatalogues($locale); } - /** - * @param string $locale - */ - private function initializeCacheCatalogue($locale) + private function initializeCacheCatalogue(string $locale): void { if (isset($this->catalogues[$locale])) { /* Catalogue already initialized. */ @@ -309,7 +338,7 @@ class Translator implements TranslatorInterface, TranslatorBagInterface $this->catalogues[$locale] = include $cache->getPath(); } - private function dumpCatalogue($locale, ConfigCacheInterface $cache) + private function dumpCatalogue($locale, ConfigCacheInterface $cache): void { $this->initializeCatalogue($locale); $fallbackContent = $this->getFallbackContent($this->catalogues[$locale]); @@ -327,14 +356,14 @@ return \$catalogue; EOF , $locale, - var_export($this->catalogues[$locale]->all(), true), + var_export($this->getAllMessages($this->catalogues[$locale]), true), $fallbackContent ); $cache->write($content, $this->catalogues[$locale]->getResources()); } - private function getFallbackContent(MessageCatalogue $catalogue) + private function getFallbackContent(MessageCatalogue $catalogue): string { $fallbackContent = ''; $current = ''; @@ -353,7 +382,7 @@ EOF , $fallbackSuffix, $fallback, - var_export($fallbackCatalogue->all(), true), + var_export($this->getAllMessages($fallbackCatalogue), true), $currentSuffix, $fallbackSuffix ); @@ -366,28 +395,27 @@ EOF private function getCatalogueCachePath($locale) { - return $this->cacheDir.'/catalogue.'.$locale.'.'.strtr(substr(base64_encode(hash('sha256', serialize($this->fallbackLocales), true)), 0, 7), '/', '_').'.php'; + return $this->cacheDir.'/catalogue.'.$locale.'.'.strtr(substr(base64_encode(hash('sha256', serialize($this->cacheVary), true)), 0, 7), '/', '_').'.php'; } - private function doLoadCatalogue($locale) + /** + * @internal + */ + protected function doLoadCatalogue($locale): void { $this->catalogues[$locale] = new MessageCatalogue($locale); if (isset($this->resources[$locale])) { foreach ($this->resources[$locale] as $resource) { if (!isset($this->loaders[$resource[0]])) { - if (\is_string($resource[1])) { - throw new RuntimeException(sprintf('No loader is registered for the "%s" format when loading the "%s" resource.', $resource[0], $resource[1])); - } - - throw new RuntimeException(sprintf('No loader is registered for the "%s" format.', $resource[0])); + throw new RuntimeException(sprintf('The "%s" translation loader is not registered.', $resource[0])); } $this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2])); } } } - private function loadFallbackCatalogues($locale) + private function loadFallbackCatalogues($locale): void { $current = $this->catalogues[$locale]; @@ -396,7 +424,7 @@ EOF $this->initializeCatalogue($fallback); } - $fallbackCatalogue = new MessageCatalogue($fallback, $this->catalogues[$fallback]->all()); + $fallbackCatalogue = new MessageCatalogue($fallback, $this->getAllMessages($this->catalogues[$fallback])); foreach ($this->catalogues[$fallback]->getResources() as $resource) { $fallbackCatalogue->addResource($resource); } @@ -407,6 +435,10 @@ EOF protected function computeFallbackLocales($locale) { + if (null === $this->parentLocales) { + $parentLocales = json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true); + } + $locales = []; foreach ($this->fallbackLocales as $fallback) { if ($fallback === $locale) { @@ -416,19 +448,27 @@ EOF $locales[] = $fallback; } - if (\function_exists('locale_parse')) { - $localeSubTags = locale_parse($locale); - if (1 < \count($localeSubTags)) { - array_pop($localeSubTags); - $fallback = locale_compose($localeSubTags); - if (false !== $fallback) { - array_unshift($locales, $fallback); + while ($locale) { + $parent = $parentLocales[$locale] ?? null; + + if ($parent) { + $locale = 'root' !== $parent ? $parent : null; + } elseif (\function_exists('locale_parse')) { + $localeSubTags = locale_parse($locale); + $locale = null; + if (1 < \count($localeSubTags)) { + array_pop($localeSubTags); + $locale = locale_compose($localeSubTags) ?: null; } + } elseif ($i = strrpos($locale, '_') ?: strrpos($locale, '-')) { + $locale = substr($locale, 0, $i); + } else { + $locale = null; + } + + if (null !== $locale) { + array_unshift($locales, $locale); } - } elseif (false !== strrchr($locale, '_')) { - array_unshift($locales, substr($locale, 0, -\strlen(strrchr($locale, '_')))); - } elseif (false !== strrchr($locale, '-')) { - array_unshift($locales, substr($locale, 0, -\strlen(strrchr($locale, '-')))); } return array_unique($locales); @@ -451,10 +491,8 @@ EOF /** * Provides the ConfigCache factory implementation, falling back to a * default implementation if necessary. - * - * @return ConfigCacheFactoryInterface $configCacheFactory */ - private function getConfigCacheFactory() + private function getConfigCacheFactory(): ConfigCacheFactoryInterface { if (!$this->configCacheFactory) { $this->configCacheFactory = new ConfigCacheFactory($this->debug); @@ -462,4 +500,21 @@ EOF return $this->configCacheFactory; } + + private function getAllMessages(MessageCatalogueInterface $catalogue): array + { + $allMessages = []; + + foreach ($catalogue->all() as $domain => $messages) { + if ($intlMessages = $catalogue->all($domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)) { + $allMessages[$domain.MessageCatalogue::INTL_DOMAIN_SUFFIX] = $intlMessages; + $messages = array_diff_key($messages, $intlMessages); + } + if ($messages) { + $allMessages[$domain] = $messages; + } + } + + return $allMessages; + } } diff --git a/vendor/symfony/translation/TranslatorInterface.php b/vendor/symfony/translation/TranslatorInterface.php index 4fbaedb45..f677d2455 100644 --- a/vendor/symfony/translation/TranslatorInterface.php +++ b/vendor/symfony/translation/TranslatorInterface.php @@ -12,13 +12,16 @@ namespace Symfony\Component\Translation; use Symfony\Component\Translation\Exception\InvalidArgumentException; +use Symfony\Contracts\Translation\LocaleAwareInterface; /** * TranslatorInterface. * * @author Fabien Potencier + * + * @deprecated since Symfony 4.2, use Symfony\Contracts\Translation\TranslatorInterface instead */ -interface TranslatorInterface +interface TranslatorInterface extends LocaleAwareInterface { /** * Translates the given message. diff --git a/vendor/symfony/translation/Util/XliffUtils.php b/vendor/symfony/translation/Util/XliffUtils.php index e4373a7d5..3ace285bf 100644 --- a/vendor/symfony/translation/Util/XliffUtils.php +++ b/vendor/symfony/translation/Util/XliffUtils.php @@ -41,7 +41,7 @@ class XliffUtils $namespace = $xliff->attributes->getNamedItem('xmlns'); if ($namespace) { if (0 !== substr_compare('urn:oasis:names:tc:xliff:document:', $namespace->nodeValue, 0, 34)) { - throw new InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s".', $namespace)); + throw new InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s"', $namespace)); } return substr($namespace, 34); @@ -61,20 +61,17 @@ class XliffUtils { $xliffVersion = static::getVersionNumber($dom); $internalErrors = libxml_use_internal_errors(true); - if ($shouldEnable = self::shouldEnableEntityLoader()) { - $disableEntities = libxml_disable_entity_loader(false); - } - try { - $isValid = @$dom->schemaValidateSource(self::getSchema($xliffVersion)); - if (!$isValid) { - return self::getXmlErrors($internalErrors); - } - } finally { - if ($shouldEnable) { - libxml_disable_entity_loader($disableEntities); - } + $disableEntities = libxml_disable_entity_loader(false); + + $isValid = @$dom->schemaValidateSource(self::getSchema($xliffVersion)); + if (!$isValid) { + libxml_disable_entity_loader($disableEntities); + + return self::getXmlErrors($internalErrors); } + libxml_disable_entity_loader($disableEntities); + $dom->normalizeDocument(); libxml_clear_errors(); @@ -83,43 +80,13 @@ class XliffUtils return []; } - private static function shouldEnableEntityLoader(): bool - { - // Version prior to 8.0 can be enabled without deprecation - if (\PHP_VERSION_ID < 80000) { - return true; - } - - static $dom, $schema; - if (null === $dom) { - $dom = new \DOMDocument(); - $dom->loadXML(''); - - $tmpfile = tempnam(sys_get_temp_dir(), 'symfony'); - register_shutdown_function(static function () use ($tmpfile) { - @unlink($tmpfile); - }); - $schema = ' - - -'; - file_put_contents($tmpfile, ' - - - -'); - } - - return !@$dom->schemaValidateSource($schema); - } - public static function getErrorsAsString(array $xmlErrors): string { $errorsAsString = ''; foreach ($xmlErrors as $error) { $errorsAsString .= sprintf("[%s %s] %s (in %s - line %d, column %d)\n", - \LIBXML_ERR_WARNING === $error['level'] ? 'WARNING' : 'ERROR', + LIBXML_ERR_WARNING === $error['level'] ? 'WARNING' : 'ERROR', $error['code'], $error['message'], $error['file'], @@ -179,7 +146,7 @@ class XliffUtils $errors = []; foreach (libxml_get_errors() as $error) { $errors[] = [ - 'level' => \LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', + 'level' => LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', 'code' => $error->code, 'message' => trim($error->message), 'file' => $error->file ?: 'n/a', diff --git a/vendor/symfony/translation/Writer/TranslationWriter.php b/vendor/symfony/translation/Writer/TranslationWriter.php index 0cad1105d..a44d24c13 100644 --- a/vendor/symfony/translation/Writer/TranslationWriter.php +++ b/vendor/symfony/translation/Writer/TranslationWriter.php @@ -38,9 +38,13 @@ class TranslationWriter implements TranslationWriterInterface /** * Disables dumper backup. + * + * @deprecated since Symfony 4.1 */ public function disableBackup() { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1.', __METHOD__), E_USER_DEPRECATED); + foreach ($this->dumpers as $dumper) { if (method_exists($dumper, 'setBackup')) { $dumper->setBackup(false); @@ -77,27 +81,10 @@ class TranslationWriter implements TranslationWriterInterface $dumper = $this->dumpers[$format]; if (isset($options['path']) && !is_dir($options['path']) && !@mkdir($options['path'], 0777, true) && !is_dir($options['path'])) { - throw new RuntimeException(sprintf('Translation Writer was not able to create directory "%s".', $options['path'])); + throw new RuntimeException(sprintf('Translation Writer was not able to create directory "%s"', $options['path'])); } // save $dumper->dump($catalogue, $options); } - - /** - * Writes translation from the catalogue according to the selected format. - * - * @param MessageCatalogue $catalogue The message catalogue to write - * @param string $format The format to use to dump the messages - * @param array $options Options that are passed to the dumper - * - * @throws InvalidArgumentException - * - * @deprecated since 3.4 will be removed in 4.0. Use write instead. - */ - public function writeTranslations(MessageCatalogue $catalogue, $format, $options = []) - { - @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 3.4 and will be removed in 4.0. Use write() instead.', __METHOD__), \E_USER_DEPRECATED); - $this->write($catalogue, $format, $options); - } } diff --git a/vendor/symfony/translation/composer.json b/vendor/symfony/translation/composer.json index 115d07950..4cd0ee036 100644 --- a/vendor/symfony/translation/composer.json +++ b/vendor/symfony/translation/composer.json @@ -16,24 +16,30 @@ } ], "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/polyfill-mbstring": "~1.0" + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^1.1.6" }, "require-dev": { - "symfony/config": "~2.8|~3.0|~4.0", + "symfony/config": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", "symfony/dependency-injection": "~3.4|~4.0", "symfony/http-kernel": "~3.4|~4.0", - "symfony/intl": "^2.8.18|^3.2.5|~4.0", + "symfony/intl": "~3.4|~4.0", + "symfony/service-contracts": "^1.1.2", "symfony/var-dumper": "~3.4|~4.0", "symfony/yaml": "~3.4|~4.0", "symfony/finder": "~2.8|~3.0|~4.0", "psr/log": "~1.0" }, "conflict": { - "symfony/config": "<2.8", + "symfony/config": "<3.4", "symfony/dependency-injection": "<3.4", "symfony/yaml": "<3.4" }, + "provide": { + "symfony/translation-implementation": "1.0" + }, "suggest": { "symfony/config": "", "symfony/yaml": "", @@ -45,5 +51,10 @@ "/Tests/" ] }, - "minimum-stability": "dev" + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "4.3-dev" + } + } } diff --git a/vendor/twig/twig/CHANGELOG b/vendor/twig/twig/CHANGELOG index 1c89d2453..d4f7f114d 100644 --- a/vendor/twig/twig/CHANGELOG +++ b/vendor/twig/twig/CHANGELOG @@ -1,26 +1,66 @@ -* 2.12.5 (2020-02-11) +# 2.14.4 (2021-03-10) + + * Add the slug filter + +# 2.14.3 (2021-01-05) + + * Fix extra bundle compat with older versions of Symfony + +# 2.14.2 (2021-01-05) + + * Fix "odd" not working for negative numbers + +# 2.14.1 (2020-10-27) + +* Fix "include(template_from_string())" + +# 2.14.0 (2020-10-21) + + * Fix sandbox support when using "include(template_from_string())" + * Make round brackets optional for one argument tests like "same as" or "divisible by" + * Add support for ES2015 style object initialisation shortcut { a } is the same as { 'a': a } + * Drop PHP 7.1 support + +# 2.13.1 (2020-08-05) + + * Fix sandbox not disabled if syntax error occurs within {% sandbox %} tag + * Fix a regression when not using a space before an operator + * Restrict callables to closures in filters + * Allow trailing commas in argument lists (in calls as well as definitions) + +# 2.13.0 (2020-07-05) + + * Fix options not taken into account when using "Michelf\MarkdownExtra" + * Fix "Twig\Extra\Intl\IntlExtension::getCountryName()" to accept "null" as a first argument + * Drop support for PHP 7.0 + * Throw exception in case non-Traversable data is passed to "filter" + * Fix context optimization on PHP 7.4 + * Fix PHP 8 compatibility + * Fix ambiguous syntax parsing + +# 2.12.5 (2020-02-11) * Add a check to ensure that iconv() is defined -* 2.12.4 (2020-02-11) +# 2.12.4 (2020-02-11) * Avoid exceptions when an intl resource is not found * Fix implementation of case-insensitivity for method names -* 2.12.3 (2019-12-28) +# 2.12.3 (2019-12-28) * fixed Symfony 5.0 support for the HTML extra extension * fixed number formatter in Intl extra extension when using a formatter prototype -* 2.12.2 (2019-11-11) +# 2.12.2 (2019-11-11) * added supported for exponential numbers -* 2.12.1 (2019-10-17) +# 2.12.1 (2019-10-17) * added the String extension in the "extra" repositories: "u" filter -* 2.12.0 (2019-10-05) +# 2.12.0 (2019-10-05) * added the spaceship operator ("<=>"), useful when using an arrow function in the "sort" filter * added support for an "arrow" function on the "sort" filter @@ -43,23 +83,23 @@ * fixed using macros in arrow functions * fixed split filter on edge case -* 2.11.3 (2019-06-18) +# 2.11.3 (2019-06-18) * display partial output (PHP buffer) when an error occurs in debug mode * fixed the filter filter (allow the result to be used several times) * fixed macro auto-import when a template contains only macros -* 2.11.2 (2019-06-05) +# 2.11.2 (2019-06-05) * fixed macro auto-import -* 2.11.1 (2019-06-04) +# 2.11.1 (2019-06-04) * added support for "Twig\Markup" instances in the "in" test (again) * allowed string operators as variables names in assignments * fixed support for macros defined in parent templates -* 2.11.0 (2019-05-31) +# 2.11.0 (2019-05-31) * added the possibility to register classes/interfaces as being safe for the escaper ("EscaperExtension::addSafeClass()") * deprecated CoreExtension::setEscaper() and CoreExtension::getEscapers() in favor of the same methods on EscaperExtension @@ -73,14 +113,14 @@ * fixed a PHP fatal error when calling a macro imported in the template in another macro * fixed wrong error message on "import" and "from" -* 2.10.0 (2019-05-14) +# 2.10.0 (2019-05-14) * deprecated "if" conditions on "for" tags * added "filter", "map", and "reduce" filters (and support for arrow functions) * fixed partial output leak when a PHP fatal error occurs * optimized context access on PHP 7.4 -* 2.9.0 (2019-04-28) +# 2.9.0 (2019-04-28) * deprecated returning "false" to remove a Node from NodeVisitorInterface::leaveNode() * allowed Twig\NodeVisitor\NodeVisitorInterface::leaveNode() to return "null" instead of "false" (same meaning) @@ -92,13 +132,13 @@ * fixed Lexer when using custom options containing the # char * added template line number to twig_get_attribute() -* 2.8.1 (2019-04-16) +# 2.8.1 (2019-04-16) * fixed EscaperNodeVisitor * deprecated passing a 3rd, 4th, and 5th arguments to the Sandbox exception classes * deprecated Node::setTemplateName() in favor of Node::setSourceContext() -* 2.8.0 (2019-04-16) +# 2.8.0 (2019-04-16) * added Traversable support for the length filter * fixed some wrong location in error messages @@ -110,12 +150,12 @@ * added support for a new whitespace trimming option ({%~ ~%}, {{~ ~}}, {#~ ~#}) * added the "column" filter -* 2.7.4 (2019-03-23) +# 2.7.4 (2019-03-23) * fixed variadic support * fixed CheckToStringNode implementation (broken when a function/filter is variadic) -* 2.7.3 (2019-03-21) +# 2.7.3 (2019-03-21) * fixed the spaceless filter so that it behaves like the spaceless tag * fixed BC break on Environment::resolveTemplate() @@ -123,15 +163,15 @@ * allowed Traversable objects to be used in the "with" tag * allowed Traversable objects to be used in the "with" argument of the "include" and "embed" tags -* 2.7.2 (2019-03-12) +# 2.7.2 (2019-03-12) * added TemplateWrapper::getTemplateName() -* 2.7.1 (2019-03-12) +# 2.7.1 (2019-03-12) * fixed class aliases -* 2.7.0 (2019-03-12) +# 2.7.0 (2019-03-12) * fixed sandbox security issue (under some circumstances, calling the __toString() method on an object was possible even if not allowed by the @@ -158,11 +198,11 @@ * changed internal code to use the namespaced classes as much as possible * deprecated Twig_Parser::isReservedMacroName() -* 2.6.2 (2019-01-14) +# 2.6.2 (2019-01-14) * fixed regression (key exists check for non ArrayObject objects) -* 2.6.1 (2019-01-14) +# 2.6.1 (2019-01-14) * fixed ArrayObject access with a null value * fixed embedded templates starting with a BOM @@ -173,7 +213,7 @@ * fixed float representation in compiled templates * added a second argument to the join filter (last separator configuration) -* 2.6.0 (2018-12-16) +# 2.6.0 (2018-12-16) * made sure twig_include returns a string * fixed multi-byte UFT-8 in escape('html_attr') @@ -182,7 +222,7 @@ * fixed GlobalsInterface extended class * fixed filesystem loader throwing an exception instead of returning false -* 2.5.0 (2018-07-13) +# 2.5.0 (2018-07-13) * deprecated using the spaceless tag at the root level of a child template (noop anyway) * deprecated the possibility to define a block in a non-capturing block in a child template @@ -192,11 +232,11 @@ * ensured that syntax errors are triggered with the right line * "js" filter now produces valid JSON -* 2.4.8 (2018-04-02) +# 2.4.8 (2018-04-02) * fixed a regression when using the "default" filter or the "defined" test on non-existing arrays -* 2.4.7 (2018-03-20) +# 2.4.7 (2018-03-20) * optimized runtime performance * optimized parser performance by inlining the constant values @@ -205,11 +245,11 @@ * added missing else clause to avoid infinite loops * fixed .. (range operator) in sandbox policy -* 2.4.6 (2018-03-03) +# 2.4.6 (2018-03-03) * fixed a regression in the way the profiler is registered in templates -* 2.4.5 (2018-03-02) +# 2.4.5 (2018-03-02) * optimized the performance of calling an extension method at runtime * optimized the performance of the dot operator for array and method calls @@ -219,7 +259,7 @@ * fixed length filter when passing an instance of IteratorAggregate * fixed Environment::resolveTemplate to accept instances of TemplateWrapper -* 2.4.4 (2017-09-27) +# 2.4.4 (2017-09-27) * added Twig_Profiler_Profile::reset() * fixed use TokenParser to return an empty Node @@ -229,19 +269,19 @@ * fixed deprecation when using Twig_Profiler_Dumper_Html * removed @final from Twig_Profiler_Dumper_Text -* 2.4.3 (2017-06-07) +# 2.4.3 (2017-06-07) * fixed namespaces introduction -* 2.4.2 (2017-06-05) +# 2.4.2 (2017-06-05) * fixed namespaces introduction -* 2.4.1 (2017-06-05) +# 2.4.1 (2017-06-05) * fixed namespaces introduction -* 2.4.0 (2017-06-05) +# 2.4.0 (2017-06-05) * added support for PHPUnit 6 when testing extensions * fixed PHP 7.2 compatibility @@ -251,15 +291,15 @@ * added namespaced aliases for all (non-deprecated) classes and interfaces * marked Twig_Filter, Twig_Function, Twig_Test, Twig_Node_Module and Twig_Profiler_Profile as final via the @final annotation -* 2.3.2 (2017-04-20) +# 2.3.2 (2017-04-20) * fixed edge case in the method cache for Twig attributes -* 2.3.1 (2017-04-18) +# 2.3.1 (2017-04-18) * fixed the empty() test -* 2.3.0 (2017-03-22) +# 2.3.0 (2017-03-22) * fixed a race condition handling when writing cache files * "length" filter now returns string length when applied to an object that does @@ -269,17 +309,17 @@ * fixed JS escaping for unicode characters with higher code points * added error message when calling `parent()` in a block that doesn't exist in the parent template -* 2.2.0 (2017-02-26) +# 2.2.0 (2017-02-26) * added a PSR-11 compatible runtime loader * added `side` argument to `trim` to allow left or right trimming only. -* 2.1.0 (2017-01-11) +# 2.1.0 (2017-01-11) * fixed twig_get_attribute() * added Twig_NodeCaptureInterface for nodes that capture all output -* 2.0.0 (2017-01-05) +# 2.0.0 (2017-01-05) * removed the C extension * moved Twig_Environment::getAttribute() to twig_get_attribute() @@ -300,20 +340,53 @@ * improved the performance of the filesystem loader * removed features that were deprecated in 1.x -* 1.42.6 (2020-XX-XX) +# 1.44.3 (2021-XX-XX) * n/a -* 1.42.5 (2020-02-11) +# 1.44.2 (2021-01-05) + + * Fix "odd" not working for negative numbers + +# 1.44.1 (2020-10-27) + + * Fix "include(template_from_string())" + +# 1.44.0 (2020-10-21) + + * Remove implicit dependency on ext/iconv in JS escaper + * Fix sandbox support when using "include(template_from_string())" + * Make round brackets optional for one argument tests like "same as" or "divisible by" + * Add support for ES2015 style object initialisation shortcut { a } is the same as { 'a': a } + * Fix filter(), map(), and reduce() to throw a RuntimeError instead of a PHP TypeError + * Drop PHP 7.1 support + +# 1.43.1 (2020-08-05) + + * Fix sandbox not disabled if syntax error occurs within {% sandbox %} tag + * Fix a regression when not using a space before an operator + * Restrict callables to closures in filters + * Allow trailing commas in argument lists (in calls as well as definitions) + +# 1.43.0 (2020-07-05) + + * Throw exception in case non-Traversable data is passed to "filter" + * Fix context optimization on PHP 7.4 + * Fix PHP 8 compatibility + * Drop PHP 5.5 5.6, and 7.0 support + * Fix ambiguous syntax parsing + * In sandbox, the `filter`, `map` and `reduce` filters require Closures in `arrow` parameter + +# 1.42.5 (2020-02-11) * Fix implementation of case-insensitivity for method names -* 1.42.4 (2019-11-11) +# 1.42.4 (2019-11-11) * optimized "block('foo') ?? 'bar" * added supported for exponential numbers -* 1.42.3 (2019-08-24) +# 1.42.3 (2019-08-24) * fixed the "split" filter when the delimiter is "0" * fixed the "empty" test on Traversable instances @@ -321,34 +394,34 @@ * fixed PHP 7.4 compatibility * bumped the minimal PHP version to 5.5 -* 1.42.2 (2019-06-18) +# 1.42.2 (2019-06-18) * Display partial output (PHP buffer) when an error occurs in debug mode -* 1.42.1 (2019-06-04) +# 1.42.1 (2019-06-04) * added support for "Twig\Markup" instances in the "in" test (again) * allowed string operators as variables names in assignments -* 1.42.0 (2019-05-31) +# 1.42.0 (2019-05-31) * fixed the "filter" filter when the argument is \Traversable but does not implement \Iterator (\SimpleXmlElement for instance) * fixed a PHP fatal error when calling a macro imported in a block in a nested block * fixed a PHP fatal error when calling a macro imported in the template in another macro * fixed wrong error message on "import" and "from" -* 1.41.0 (2019-05-14) +# 1.41.0 (2019-05-14) * fixed support for PHP 7.4 * added "filter", "map", and "reduce" filters (and support for arrow functions) * fixed partial output leak when a PHP fatal error occurs * optimized context access on PHP 7.4 -* 1.40.1 (2019-04-29) +# 1.40.1 (2019-04-29) -* fixed regression in NodeTraverser +# fixed regression in NodeTraverser -* 1.40.0 (2019-04-28) +# 1.40.0 (2019-04-28) * allowed Twig\NodeVisitor\NodeVisitorInterface::leaveNode() to return "null" instead of "false" (same meaning) * added the "apply" tag as a replacement for the "filter" tag @@ -357,11 +430,11 @@ * fixed Lexer when using custom options containing the # char * fixed "import" when macros are stored in a template string -* 1.39.1 (2019-04-16) +# 1.39.1 (2019-04-16) * fixed EscaperNodeVisitor -* 1.39.0 (2019-04-16) +# 1.39.0 (2019-04-16) * added Traversable support for the length filter * fixed some wrong location in error messages @@ -372,11 +445,11 @@ * fixed "include" with "ignore missing" when an error loading occurs in the included template * added support for a new whitespace trimming option ({%~ ~%}, {{~ ~}}, {#~ ~#}) -* 1.38.4 (2019-03-23) +# 1.38.4 (2019-03-23) * fixed CheckToStringNode implementation (broken when a function/filter is variadic) -* 1.38.3 (2019-03-21) +# 1.38.3 (2019-03-21) * fixed the spaceless filter so that it behaves like the spaceless tag * fixed BC break on Environment::resolveTemplate() @@ -384,15 +457,15 @@ * allowed Traversable objects to be used in the "with" tag * allowed Traversable objects to be used in the "with" argument of the "include" and "embed" tags -* 1.38.2 (2019-03-12) +# 1.38.2 (2019-03-12) * added TemplateWrapper::getTemplateName() -* 1.38.1 (2019-03-12) +# 1.38.1 (2019-03-12) * fixed class aliases -* 1.38.0 (2019-03-12) +# 1.38.0 (2019-03-12) * fixed sandbox security issue (under some circumstances, calling the __toString() method on an object was possible even if not allowed by the @@ -409,12 +482,12 @@ * added Twig\Loader\ChainLoader::getLoaders() * changed internal code to use the namespaced classes as much as possible -* 1.37.1 (2019-01-14) +# 1.37.1 (2019-01-14) * fixed regression (key exists check for non ArrayObject objects) * fixed logic in TemplateWrapper -* 1.37.0 (2019-01-14) +# 1.37.0 (2019-01-14) * fixed ArrayObject access with a null value * fixed embedded templates starting with a BOM @@ -424,7 +497,7 @@ * fixed float representation in compiled templates * added a second argument to the join filter (last separator configuration) -* 1.36.0 (2018-12-16) +# 1.36.0 (2018-12-16) * made sure twig_include returns a string * fixed multi-byte UFT-8 in escape('html_attr') @@ -433,24 +506,24 @@ * fixed GlobalsInterface extended class * fixed filesystem loader throwing an exception instead of returning false -* 1.35.4 (2018-07-13) +# 1.35.4 (2018-07-13) * ensured that syntax errors are triggered with the right line * added the Symfony ctype polyfill as a dependency * "js" filter now produces valid JSON -* 1.35.3 (2018-03-20) +# 1.35.3 (2018-03-20) * fixed block names unicity * fixed counting children of SimpleXMLElement objects * added missing else clause to avoid infinite loops * fixed .. (range operator) in sandbox policy -* 1.35.2 (2018-03-03) +# 1.35.2 (2018-03-03) * fixed a regression in the way the profiler is registered in templates -* 1.35.1 (2018-03-02) +# 1.35.1 (2018-03-02) * added an exception when using "===" instead of "same as" * fixed possible array to string conversion concealing actual error @@ -458,31 +531,31 @@ * fixed length filter when passing an instance of IteratorAggregate * fixed Environment::resolveTemplate to accept instances of TemplateWrapper -* 1.35.0 (2017-09-27) +# 1.35.0 (2017-09-27) * added Twig_Profiler_Profile::reset() * fixed use TokenParser to return an empty Node * added RuntimeExtensionInterface * added circular reference detection when loading templates -* 1.34.4 (2017-07-04) +# 1.34.4 (2017-07-04) * added support for runtime loaders in IntegrationTestCase * fixed deprecation when using Twig_Profiler_Dumper_Html -* 1.34.3 (2017-06-07) +# 1.34.3 (2017-06-07) * fixed namespaces introduction -* 1.34.2 (2017-06-05) +# 1.34.2 (2017-06-05) * fixed namespaces introduction -* 1.34.1 (2017-06-05) +# 1.34.1 (2017-06-05) * fixed namespaces introduction -* 1.34.0 (2017-06-05) +# 1.34.0 (2017-06-05) * added support for PHPUnit 6 when testing extensions * fixed PHP 7.2 compatibility @@ -492,15 +565,15 @@ * dropped HHVM support * dropped PHP 5.2 support -* 1.33.2 (2017-04-20) +# 1.33.2 (2017-04-20) * fixed edge case in the method cache for Twig attributes -* 1.33.1 (2017-04-18) +# 1.33.1 (2017-04-18) * fixed the empty() test -* 1.33.0 (2017-03-22) +# 1.33.0 (2017-03-22) * fixed a race condition handling when writing cache files * "length" filter now returns string length when applied to an object that does @@ -509,13 +582,13 @@ objects implement __toString() but not \Countable * fixed JS escaping for unicode characters with higher code points -* 1.32.0 (2017-02-26) +# 1.32.0 (2017-02-26) * fixed deprecation notice in Twig_Util_DeprecationCollector * added a PSR-11 compatible runtime loader * added `side` argument to `trim` to allow left or right trimming only. -* 1.31.0 (2017-01-11) +# 1.31.0 (2017-01-11) * added Twig_NodeCaptureInterface for nodes that capture all output * fixed marking the environment as initialized too early @@ -523,13 +596,13 @@ * turned fatal error into exception when a previously generated cache is corrupted * fixed offline cache warm-ups for embedded templates -* 1.30.0 (2016-12-23) +# 1.30.0 (2016-12-23) * added Twig_FactoryRuntimeLoader * deprecated function/test/filter/tag overriding * deprecated the "disable_c_ext" attribute on Twig_Node_Expression_GetAttr -* 1.29.0 (2016-12-13) +# 1.29.0 (2016-12-13) * fixed sandbox being left enabled if an exception is thrown while rendering * marked some classes as being final (via @final) @@ -538,16 +611,16 @@ * deprecated silent display of undefined blocks * deprecated support for mbstring.func_overload != 0 -* 1.28.2 (2016-11-23) +# 1.28.2 (2016-11-23) * fixed precedence between getFoo() and isFoo() in Twig_Template::getAttribute() * improved a deprecation message -* 1.28.1 (2016-11-18) +# 1.28.1 (2016-11-18) * fixed block() function when used with a template argument -* 1.28.0 (2016-11-17) +# 1.28.0 (2016-11-17) * added support for the PHP 7 null coalescing operator for the ?? Twig implementation * exposed a way to access template data and methods in a portable way @@ -557,7 +630,7 @@ * added "is defined" support for block() and constant() * optimized the way attributes are fetched -* 1.27.0 (2016-10-25) +# 1.27.0 (2016-10-25) * deprecated Twig_Parser::getEnvironment() * deprecated Twig_Parser::addHandler() and Twig_Parser::addNodeVisitor() @@ -575,13 +648,13 @@ * fixed template paths when a template name contains a protocol like vfs:// * improved debugging with Twig_Sandbox_SecurityError exceptions for disallowed methods and properties -* 1.26.1 (2016-10-05) +# 1.26.1 (2016-10-05) * removed template source code from generated template classes when debug is disabled * fixed default implementation of Twig_Template::getDebugInfo() for better BC * fixed regression on static calls for functions/filters/tests -* 1.26.0 (2016-10-02) +# 1.26.0 (2016-10-02) * added template cache invalidation based on more environment options * added a missing deprecation notice @@ -589,7 +662,7 @@ * allowed filters/functions/tests implementation to use a different class than the extension they belong to * deprecated Twig_ExtensionInterface::getName() -* 1.25.0 (2016-09-21) +# 1.25.0 (2016-09-21) * changed the way we store template source in template classes * removed usage of realpath in cache keys @@ -599,13 +672,13 @@ * deprecated Twig_Environment::getLexer(), Twig_Environment::getParser(), Twig_Environment::getCompiler() * deprecated Twig_Compiler::getFilename() -* 1.24.2 (2016-09-01) +# 1.24.2 (2016-09-01) * fixed static callables * fixed a potential PHP warning when loading the cache * fixed a case where the autoescaping does not work as expected -* 1.24.1 (2016-05-30) +# 1.24.1 (2016-05-30) * fixed reserved keywords (forbids true, false, null and none keywords for variables names) * fixed support for PHP7 (Throwable support) @@ -614,36 +687,36 @@ getTokenParsers(), getTags(), getNodeVisitors(), getUnaryOperators(), getBinaryOperators(), getFunctions(), getFilters(), getGlobals(), initGlobals(), initExtensions(), and initExtension() -* 1.24.0 (2016-01-25) +# 1.24.0 (2016-01-25) * adding support for the ?? operator * fixed the defined test when used on a constant, a map, or a sequence * undeprecated _self (should only be used to get the template name, not the template instance) * fixed parsing on PHP7 -* 1.23.3 (2016-01-11) +# 1.23.3 (2016-01-11) * fixed typo -* 1.23.2 (2015-01-11) +# 1.23.2 (2015-01-11) * added versions in deprecated messages * made file cache tolerant for trailing (back)slashes on directory configuration * deprecated unused Twig_Node_Expression_ExtensionReference class -* 1.23.1 (2015-11-05) +# 1.23.1 (2015-11-05) * fixed some exception messages which triggered PHP warnings * fixed BC on Twig_Test_NodeTestCase -* 1.23.0 (2015-10-29) +# 1.23.0 (2015-10-29) * deprecated the possibility to override an extension by registering another one with the same name * deprecated Twig_ExtensionInterface::getGlobals() (added Twig_Extension_GlobalsInterface for BC) * deprecated Twig_ExtensionInterface::initRuntime() (added Twig_Extension_InitRuntimeInterface for BC) * deprecated Twig_Environment::computeAlternatives() -* 1.22.3 (2015-10-13) +# 1.22.3 (2015-10-13) * fixed regression when using null as a cache strategy * improved performance when checking template freshness @@ -652,15 +725,15 @@ * fixed logic for custom escapers to call them even on integers and null values * changed template cache names to take into account the Twig C extension -* 1.22.2 (2015-09-22) +# 1.22.2 (2015-09-22) * fixed a race condition in template loading -* 1.22.1 (2015-09-15) +# 1.22.1 (2015-09-15) * fixed regression in template_from_string -* 1.22.0 (2015-09-13) +# 1.22.0 (2015-09-13) * made Twig_Test_IntegrationTestCase more flexible * added an option to force PHP bytecode invalidation when writing a compiled template into the cache @@ -671,23 +744,23 @@ * added a way to override the filesystem template cache system * added a way to get the original template source from Twig_Template -* 1.21.2 (2015-09-09) +# 1.21.2 (2015-09-09) * fixed variable names for the deprecation triggering code * fixed escaping strategy detection based on filename * added Traversable support for replace, merge, and sort * deprecated support for character by character replacement for the "replace" filter -* 1.21.1 (2015-08-26) +# 1.21.1 (2015-08-26) * fixed regression when using the deprecated Twig_Test_* classes -* 1.21.0 (2015-08-24) +# 1.21.0 (2015-08-24) * added deprecation notices for deprecated features * added a deprecation "framework" for filters/functions/tests and test fixtures -* 1.20.0 (2015-08-12) +# 1.20.0 (2015-08-12) * forbid access to the Twig environment from templates and internal parts of Twig_Template * fixed limited RCEs when in sandbox mode @@ -696,7 +769,7 @@ * added Twig_BaseNodeVisitor to ease the compatibility of node visitors between 1.x and 2.x -* 1.19.0 (2015-07-31) +# 1.19.0 (2015-07-31) * fixed wrong error message when including an undefined template in a child template * added support for variadic filters, functions, and tests @@ -706,19 +779,19 @@ * deprecated Twig_Environment::clearTemplateCache() * fixed sandbox disabling when using the include function -* 1.18.2 (2015-06-06) +# 1.18.2 (2015-06-06) * fixed template/line guessing in exceptions for nested templates * optimized the number of inodes and the size of realpath cache when using the cache -* 1.18.1 (2015-04-19) +# 1.18.1 (2015-04-19) * fixed memory leaks in the C extension * deprecated Twig_Loader_String * fixed the slice filter when used with a SimpleXMLElement object * fixed filesystem loader when trying to load non-files (like directories) -* 1.18.0 (2015-01-25) +# 1.18.0 (2015-01-25) * fixed some error messages where the line was wrong (unknown variables or argument names) * added a new way to customize the main Module node (via empty nodes) @@ -726,18 +799,18 @@ * added a profiler * fixed filesystem loader cache when different file paths are used for the same template -* 1.17.0 (2015-01-14) +# 1.17.0 (2015-01-14) * added a 'filename' autoescaping strategy, which dynamically chooses the autoescaping strategy for a template based on template file extension. -* 1.16.3 (2014-12-25) +# 1.16.3 (2014-12-25) * fixed regression for dynamic parent templates * fixed cache management with statcache * fixed a regression in the slice filter -* 1.16.2 (2014-10-17) +# 1.16.2 (2014-10-17) * fixed timezone on dates as strings * fixed 2-words test names when a custom node class is not used @@ -748,7 +821,7 @@ * fixed a regression in the in operator * fixed a regression in the slice filter -* 1.16.1 (2014-10-10) +# 1.16.1 (2014-10-10) * improved error reporting in a sandboxed template * fixed missing error file/line information under certain circumstances @@ -758,20 +831,20 @@ * fixed for mb function overload mb_substr acting different * fixed the attribute() function when passing a variable for the arguments -* 1.16.0 (2014-07-05) +# 1.16.0 (2014-07-05) * changed url_encode to always encode according to RFC 3986 * fixed inheritance in a 'use'-hierarchy * removed the __toString policy check when the sandbox is disabled * fixed recursively calling blocks in templates with inheritance -* 1.15.1 (2014-02-13) +# 1.15.1 (2014-02-13) * fixed the conversion of the special '0000-00-00 00:00' date * added an error message when trying to import an undefined block from a trait * fixed a C extension crash when accessing defined but uninitialized property. -* 1.15.0 (2013-12-06) +# 1.15.0 (2013-12-06) * made ignoreStrictCheck in Template::getAttribute() works with __call() methods throwing BadMethodCallException * added min and max functions @@ -781,19 +854,19 @@ * added a source function to include the content of a template without rendering it * fixed the C extension sandbox behavior when get or set is prepend to method name -* 1.14.2 (2013-10-30) +# 1.14.2 (2013-10-30) * fixed error filename/line when an error occurs in an included file * allowed operators that contain whitespaces to have more than one whitespace * allowed tests to be made of 1 or 2 words (like "same as" or "divisible by") -* 1.14.1 (2013-10-15) +# 1.14.1 (2013-10-15) * made it possible to use named operators as variables * fixed the possibility to have a variable named 'matches' * added support for PHP 5.5 DateTimeInterface -* 1.14.0 (2013-10-03) +# 1.14.0 (2013-10-03) * fixed usage of the html_attr escaping strategy to avoid double-escaping with the html strategy * added new operators: ends with, starts with, and matches @@ -805,12 +878,12 @@ * fixed template_from_string when the template includes or extends other ones * fixed a crash of the C extension on an edge case -* 1.13.2 (2013-08-03) +# 1.13.2 (2013-08-03) * fixed the error line number for an error occurs in and embedded template * fixed crashes of the C extension on some edge cases -* 1.13.1 (2013-06-06) +# 1.13.1 (2013-06-06) * added the possibility to ignore the filesystem constructor argument in Twig_Loader_Filesystem * fixed Twig_Loader_Chain::exists() for a loader which implements Twig_ExistsLoaderInterface @@ -818,7 +891,7 @@ * added support for object instances as the second argument of the constant test * fixed the include function when used in an assignment -* 1.13.0 (2013-05-10) +# 1.13.0 (2013-05-10) * fixed getting a numeric-like item on a variable ('09' for instance) * fixed getting a boolean or float key on an array, so it is consistent with PHP's array access: @@ -827,7 +900,7 @@ * changed ☃ to § in tests * enforced usage of named arguments after positional ones -* 1.12.3 (2013-04-08) +# 1.12.3 (2013-04-08) * fixed a security issue in the filesystem loader where it was possible to include a template one level above the configured path @@ -835,25 +908,25 @@ * added a batch filter * added support for encoding an array as query string in the url_encode filter -* 1.12.2 (2013-02-09) +# 1.12.2 (2013-02-09) * fixed the timezone used by the date filter and function when the given date contains a timezone (like 2010-01-28T15:00:00+02:00) * fixed globals when getGlobals is called early on * added the first and last filter -* 1.12.1 (2013-01-15) +# 1.12.1 (2013-01-15) * added support for object instances as the second argument of the constant function * relaxed globals management to avoid a BC break * added support for {{ some_string[:2] }} -* 1.12.0 (2013-01-08) +# 1.12.0 (2013-01-08) * added verbatim as an alias for the raw tag to avoid confusion with the raw filter * fixed registration of tests and functions as anonymous functions * fixed globals management -* 1.12.0-RC1 (2012-12-29) +# 1.12.0-RC1 (2012-12-29) * added an include function (does the same as the include tag but in a more flexible way) * added the ability to use any PHP callable to define filters, functions, and tests @@ -863,14 +936,14 @@ * moved filters/functions/tests syntax errors to the parser * added support for extended ternary operator syntaxes -* 1.11.1 (2012-11-11) +# 1.11.1 (2012-11-11) * fixed debug info line numbering (was off by 2) * fixed escaping when calling a macro inside another one (regression introduced in 1.9.1) * optimized variable access on PHP 5.4 * fixed a crash of the C extension when an exception was thrown from a macro called without being imported (using _self.XXX) -* 1.11.0 (2012-11-07) +# 1.11.0 (2012-11-07) * fixed macro compilation when a variable name is a PHP reserved keyword * changed the date filter behavior to always apply the default timezone, except if false is passed as the timezone @@ -880,41 +953,41 @@ * optimized the way Twig exceptions are managed (to make them faster) * added Twig_ExistsLoaderInterface (implementing this interface in your loader make the chain loader much faster) -* 1.10.3 (2012-10-19) +# 1.10.3 (2012-10-19) * fixed wrong template location in some error messages * reverted a BC break introduced in 1.10.2 * added a split filter -* 1.10.2 (2012-10-15) +# 1.10.2 (2012-10-15) * fixed macro calls on PHP 5.4 -* 1.10.1 (2012-10-15) +# 1.10.1 (2012-10-15) * made a speed optimization to macro calls when imported via the "import" tag * fixed C extension compilation on Windows * fixed a segfault in the C extension when using DateTime objects -* 1.10.0 (2012-09-28) +# 1.10.0 (2012-09-28) * extracted functional tests framework to make it reusable for third-party extensions * added namespaced templates support in Twig_Loader_Filesystem * added Twig_Loader_Filesystem::prependPath() * fixed an error when a token parser pass a closure as a test to the subparse() method -* 1.9.2 (2012-08-25) +# 1.9.2 (2012-08-25) * fixed the in operator for objects that contain circular references * fixed the C extension when accessing a public property of an object implementing the \ArrayAccess interface -* 1.9.1 (2012-07-22) +# 1.9.1 (2012-07-22) * optimized macro calls when auto-escaping is on * fixed wrong parent class for Twig_Function_Node * made Twig_Loader_Chain more explicit about problems -* 1.9.0 (2012-07-13) +# 1.9.0 (2012-07-13) * made the parsing independent of the template loaders * fixed exception trace when an error occurs when rendering a child template @@ -922,26 +995,26 @@ * fixed nested embed tag calls * added the date_modify filter -* 1.8.3 (2012-06-17) +# 1.8.3 (2012-06-17) * fixed paths in the filesystem loader when passing a path that ends with a slash or a backslash * fixed escaping when a project defines a function named html or js * fixed chmod mode to apply the umask correctly -* 1.8.2 (2012-05-30) +# 1.8.2 (2012-05-30) * added the abs filter * fixed a regression when using a number in template attributes * fixed compiler when mbstring.func_overload is set to 2 * fixed DateTimeZone support in date filter -* 1.8.1 (2012-05-17) +# 1.8.1 (2012-05-17) * fixed a regression when dealing with SimpleXMLElement instances in templates * fixed "is_safe" value for the "dump" function when "html_errors" is not defined in php.ini * switched to use mbstring whenever possible instead of iconv (you might need to update your encoding as mbstring and iconv encoding names sometimes differ) -* 1.8.0 (2012-05-08) +# 1.8.0 (2012-05-08) * enforced interface when adding tests, filters, functions, and node visitors from extensions * fixed a side-effect of the date filter where the timezone might be changed @@ -950,7 +1023,7 @@ * changed the autoescape option to also accept a supported escaping strategy (for BC, true is equivalent to html) * added an embed tag -* 1.7.0 (2012-04-24) +# 1.7.0 (2012-04-24) * fixed a PHP warning when using CIFS * fixed template line number in some exceptions @@ -964,30 +1037,30 @@ * fixed filesystem loader freshness logic for high traffic websites * fixed random function when charset is null -* 1.6.5 (2012-04-11) +# 1.6.5 (2012-04-11) * fixed a regression when a template only extends another one without defining any blocks -* 1.6.4 (2012-04-02) +# 1.6.4 (2012-04-02) * fixed PHP notice in Twig_Error::guessTemplateLine() introduced in 1.6.3 * fixed performance when compiling large files * optimized parent template creation when the template does not use dynamic inheritance -* 1.6.3 (2012-03-22) +# 1.6.3 (2012-03-22) * fixed usage of Z_ADDREF_P for PHP 5.2 in the C extension * fixed compilation of numeric values used in templates when using a locale where the decimal separator is not a dot * made the strategy used to guess the real template file name and line number in exception messages much faster and more accurate -* 1.6.2 (2012-03-18) +# 1.6.2 (2012-03-18) * fixed sandbox mode when used with inheritance * added preserveKeys support for the slice filter * fixed the date filter when a DateTime instance is passed with a specific timezone * added a trim filter -* 1.6.1 (2012-02-29) +# 1.6.1 (2012-02-29) * fixed Twig C extension * removed the creation of Twig_Markup instances when not needed @@ -995,7 +1068,7 @@ * fixed the slice filter on strings when the length is not specified * fixed the creation of the cache directory in case of a race condition -* 1.6.0 (2012-02-04) +# 1.6.0 (2012-02-04) * fixed raw blocks when used with the whitespace trim option * made a speed optimization to macro calls when imported via the "from" tag @@ -1010,22 +1083,22 @@ * added recursive parsing support in the parser * added string and integer handling for the random function -* 1.5.1 (2012-01-05) +# 1.5.1 (2012-01-05) * fixed a regression when parsing strings -* 1.5.0 (2012-01-04) +# 1.5.0 (2012-01-04) * added Traversable objects support for the join filter -* 1.5.0-RC2 (2011-12-30) +# 1.5.0-RC2 (2011-12-30) * added a way to set the default global date interval format * fixed the date filter for DateInterval instances (setTimezone() does not exist for them) * refactored Twig_Template::display() to ease its extension * added a number_format filter -* 1.5.0-RC1 (2011-12-26) +# 1.5.0-RC1 (2011-12-26) * removed the need to quote hash keys * allowed hash keys to be any expression @@ -1040,19 +1113,19 @@ * added string interpolation support * enhanced exceptions for unknown filters, functions, tests, and tags -* 1.4.0 (2011-12-07) +# 1.4.0 (2011-12-07) * fixed lexer when using big numbers (> PHP_INT_MAX) * added missing preserveKeys argument to the reverse filter * fixed macros containing filter tag calls -* 1.4.0-RC2 (2011-11-27) +# 1.4.0-RC2 (2011-11-27) * removed usage of Reflection in Twig_Template::getAttribute() * added a C extension that can optionally replace Twig_Template::getAttribute() * added negative timestamp support to the date filter -* 1.4.0-RC1 (2011-11-20) +# 1.4.0-RC1 (2011-11-20) * optimized variable access when using PHP 5.4 * changed the precedence of the .. operator to be more consistent with languages that implements such a feature like Ruby @@ -1070,11 +1143,11 @@ * moved all node manipulations outside the compile() Node method * made several speed optimizations -* 1.3.0 (2011-10-08) +# 1.3.0 (2011-10-08) no changes -* 1.3.0-RC1 (2011-10-04) +# 1.3.0-RC1 (2011-10-04) * added an optimization for the parent() function * added cache reloading when auto_reload is true and an extension has been modified @@ -1082,11 +1155,11 @@ no changes * allowed empty templates to be used as traits * added traits support for the "parent" function -* 1.2.0 (2011-09-13) +# 1.2.0 (2011-09-13) no changes -* 1.2.0-RC1 (2011-09-10) +# 1.2.0-RC1 (2011-09-10) * enhanced the exception when a tag remains unclosed * added support for empty Countable objects for the "empty" test @@ -1103,7 +1176,7 @@ no changes * removed the possibility to use the "extends" tag from a block * added "if" modifier support to "for" loops -* 1.1.2 (2011-07-30) +# 1.1.2 (2011-07-30) * fixed json_encode filter on PHP 5.2 * fixed regression introduced in 1.1.1 ({{ block(foo|lower) }}) @@ -1113,28 +1186,28 @@ no changes * fixed a parsing problem when a large chunk of text is enclosed in a comment tag * added PHPDoc for all Token parsers and Core extension functions -* 1.1.1 (2011-07-17) +# 1.1.1 (2011-07-17) * added a performance optimization in the Optimizer (also helps to lower the number of nested level calls) * made some performance improvement for some edge cases -* 1.1.0 (2011-06-28) +# 1.1.0 (2011-06-28) * fixed json_encode filter -* 1.1.0-RC3 (2011-06-24) +# 1.1.0-RC3 (2011-06-24) * fixed method case-sensitivity when using the sandbox mode * added timezone support for the date filter * fixed possible security problems with NUL bytes -* 1.1.0-RC2 (2011-06-16) +# 1.1.0-RC2 (2011-06-16) * added an exception when the template passed to "use" is not a string * made 'a.b is defined' not throw an exception if a is not defined (in strict mode) * added {% line \d+ %} directive -* 1.1.0-RC1 (2011-05-28) +# 1.1.0-RC1 (2011-05-28) Flush your cache after upgrading. @@ -1148,13 +1221,13 @@ Flush your cache after upgrading. * wrapped all compilation and runtime exceptions with Twig_Error_Runtime and added logic to guess the template name and line * moved display() method to Twig_Template (generated templates should now use doDisplay() instead) -* 1.0.0 (2011-03-27) +# 1.0.0 (2011-03-27) * fixed output when using mbstring * fixed duplicate call of methods when using the sandbox * made the charset configurable for the escape filter -* 1.0.0-RC2 (2011-02-21) +# 1.0.0-RC2 (2011-02-21) * changed the way {% set %} works when capturing (the content is now marked as safe) * added support for macro name in the endmacro tag @@ -1165,7 +1238,7 @@ Flush your cache after upgrading. * removed coupling between Twig_Node and Twig_Template * fixed the ternary operator precedence rule -* 1.0.0-RC1 (2011-01-09) +# 1.0.0-RC1 (2011-01-09) Backward incompatibilities: @@ -1191,7 +1264,7 @@ Changes: * the "default" filter now uses the "empty" test instead of just checking for null * added the "empty" test -* 0.9.10 (2010-12-16) +# 0.9.10 (2010-12-16) Backward incompatibilities: @@ -1226,7 +1299,7 @@ Changes: * added an Optimizer extension (enabled by default; optimizes "for" loops and "raw" filters) * added priority to node visitors -* 0.9.9 (2010-11-28) +# 0.9.9 (2010-11-28) Backward incompatibilities: * the self special variable has been renamed to _self @@ -1275,7 +1348,7 @@ Changes: * renamed self to _self (to avoid conflict) * fixed Twig_Template::getAttribute() for protected properties -* 0.9.8 (2010-06-28) +# 0.9.8 (2010-06-28) Backward incompatibilities: * the trans tag plural count is now attached to the plural tag: @@ -1290,7 +1363,7 @@ Backward incompatibilities: * fixed set tag when used with a capture * fixed type hinting for Twig_Environment::addFilter() method -* 0.9.7 (2010-06-12) +# 0.9.7 (2010-06-12) Backward incompatibilities: * changed 'as' to '=' for the set tag ({% set title as "Title" %} must now be {% set title = "Title" %}) @@ -1317,7 +1390,7 @@ Backward incompatibilities: * fixed sandbox mode (__toString() method check was not enforced if called implicitly from a simple statement like {{ article }}) * added an exception when a child template has a non-empty body (as it is always ignored when rendering) -* 0.9.6 (2010-05-12) +# 0.9.6 (2010-05-12) * fixed variables defined outside a loop and for which the value changes in a for loop * fixed the test suite for PHP 5.2 and older versions of PHPUnit @@ -1334,7 +1407,7 @@ Backward incompatibilities: * added support for escaping strategy in the autoescape tag * fixed lexer when a template has a big chunk of text between/in a block -* 0.9.5 (2010-01-20) +# 0.9.5 (2010-01-20) As for any new release, don't forget to remove all cached templates after upgrading. @@ -1371,7 +1444,7 @@ stable). * added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes) * enhanced some error messages to provide better feedback in case of parsing errors -* 0.9.4 (2009-12-02) +# 0.9.4 (2009-12-02) If you have custom loaders, you MUST upgrade them for this release: The Twig_Loader base class has been removed, and the Twig_LoaderInterface has also @@ -1384,7 +1457,7 @@ been changed (see the source code for more information or the documentation). * fixed bug when the filename of a template contains */ * refactored loaders -* 0.9.3 (2009-11-11) +# 0.9.3 (2009-11-11) This release is NOT backward compatible with the previous releases. @@ -1413,7 +1486,7 @@ This release is NOT backward compatible with the previous releases. * extended set tag to support expression as value ({% set foo as 'foo' ~ 'bar' %} ) * fixed bug when \ was used in HTML -* 0.9.2 (2009-10-29) +# 0.9.2 (2009-10-29) * made some speed optimizations * changed the cache extension to .php @@ -1431,7 +1504,7 @@ This release is NOT backward compatible with the previous releases. * enhanced some error messages to ease debugging * fixed empty cache files when the template contains an error -* 0.9.1 (2009-10-14) +# 0.9.1 (2009-10-14) * fixed a bug in PHP 5.2.6 * fixed numbers with one than one decimal @@ -1439,6 +1512,6 @@ This release is NOT backward compatible with the previous releases. * made small speed optimizations * made minor tweaks to allow better extensibility and flexibility -* 0.9.0 (2009-10-12) +# 0.9.0 (2009-10-12) * Initial release diff --git a/vendor/twig/twig/LICENSE b/vendor/twig/twig/LICENSE index 5e8a0b8b9..4371e4233 100644 --- a/vendor/twig/twig/LICENSE +++ b/vendor/twig/twig/LICENSE @@ -1,29 +1,27 @@ -Copyright (c) 2009-2020 by the Twig Team. +Copyright (c) 2009-2021 by the Twig Team. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +All rights reserved. - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Twig nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/twig/twig/composer.json b/vendor/twig/twig/composer.json index 0d1c0ad1b..8f45b4bd3 100644 --- a/vendor/twig/twig/composer.json +++ b/vendor/twig/twig/composer.json @@ -5,6 +5,7 @@ "keywords": ["templating"], "homepage": "https://twig.symfony.com", "license": "BSD-3-Clause", + "minimum-stability": "dev", "authors": [ { "name": "Fabien Potencier", @@ -23,12 +24,12 @@ } ], "require": { - "php": "^7.0", + "php": ">=7.2.5", "symfony/polyfill-mbstring": "^1.3", "symfony/polyfill-ctype": "^1.8" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4|^5.0", + "symfony/phpunit-bridge": "^4.4.9|^5.0.9", "psr/container": "^1.0" }, "autoload": { @@ -46,7 +47,7 @@ }, "extra": { "branch-alias": { - "dev-master": "2.12-dev" + "dev-master": "2.14-dev" } } } diff --git a/vendor/twig/twig/doc/_build/Makefile b/vendor/twig/twig/doc/_build/Makefile new file mode 100644 index 000000000..25b660056 --- /dev/null +++ b/vendor/twig/twig/doc/_build/Makefile @@ -0,0 +1,153 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = . + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -c $(BUILDDIR) -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) ../ +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Symfony.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Symfony.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/Symfony" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Symfony" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/vendor/twig/twig/doc/_build/conf.py b/vendor/twig/twig/doc/_build/conf.py new file mode 100644 index 000000000..1e3a8abfc --- /dev/null +++ b/vendor/twig/twig/doc/_build/conf.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# +# Symfony documentation build configuration file, created by +# sphinx-quickstart on Sat Jul 28 21:58:57 2012. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.append(os.path.abspath('_exts')) + +# adding PhpLexer +from sphinx.highlighting import lexers +from pygments.lexers.special import TextLexer +from pygments.lexers.text import RstLexer +from pygments.lexers.web import PhpLexer + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = '1.8.5' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [ + 'sphinx.ext.autodoc', 'sphinx.ext.doctest', + 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.ifconfig', + 'sphinx.ext.viewcode', 'sphinx.ext.extlinks', + 'sensio.sphinx.codeblock', 'sensio.sphinx.configurationblock', 'sensio.sphinx.phpcode', 'sensio.sphinx.bestpractice' +] + +#spelling_show_sugestions=True +#spelling_lang='en_US' +#spelling_word_list_filename='_build/spelling_word_list.txt' + +# Add any paths that contain templates here, relative to this directory. +# templates_path = ['_theme/_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'Twig' +copyright = '' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +# version = '2.2' +# The full version, including alpha/beta/rc tags. +# release = '2.2.13' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +#pygments_style = 'symfonycom.sphinx.SensioStyle' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# -- Settings for symfony doc extension --------------------------------------------------- + +# enable highlighting for PHP code not between ```` by default +lexers['php'] = PhpLexer(startinline=True) +lexers['rst'] = RstLexer() + +config_block = { + 'rst': 'reStructuredText', +} + +# don't enable Sphinx Domains +primary_domain = None + +# set url for API links +#api_url = 'https://github.com/symfony/symfony/blob/master/src/%s.php' + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "sphinx_rtd_theme" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + 'logo_only': True, + 'prev_next_buttons_location': None, + 'style_nav_header_background': '#f0f0f0' +} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = '_static/symfony-logo.svg' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] +#html_css_files = ['rtd_custom.css'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Twig' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +#latex_documents = [] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +#man_pages = [] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +#texinfo_documents = [] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# Use PHP syntax highlighting in code examples by default +highlight_language='php' diff --git a/vendor/twig/twig/doc/advanced.rst b/vendor/twig/twig/doc/advanced.rst index bd9f5a41b..41fd156bc 100644 --- a/vendor/twig/twig/doc/advanced.rst +++ b/vendor/twig/twig/doc/advanced.rst @@ -182,7 +182,7 @@ If you want to access the current environment instance in your filter, set the ``needs_environment`` option to ``true``; Twig will pass the current environment as the first argument to the filter call:: - $filter = new \Twig\TwigFilter('rot13', function (Twig_Environment $env, $string) { + $filter = new \Twig\TwigFilter('rot13', function (\Twig\Environment $env, $string) { // get the current charset for instance $charset = $env->getCharset(); @@ -201,7 +201,7 @@ the first argument to the filter call (or the second one if // ... }, ['needs_context' => true]); - $filter = new \Twig\TwigFilter('rot13', function (Twig_Environment $env, $context, $string) { + $filter = new \Twig\TwigFilter('rot13', function (\Twig\Environment $env, $context, $string) { // ... }, ['needs_context' => true, 'needs_environment' => true]); @@ -326,21 +326,27 @@ When creating tests you can use the ``node_class`` option to provide custom test compilation. This is useful if your test can be compiled into PHP primitives. This is used by many of the tests built into Twig:: - $twig = new \Twig\Environment($loader); - $test = new \Twig\TwigTest( + namespace App; + + use Twig\Environment; + use Twig\Node\Expression\TestExpression; + use Twig\TwigTest; + + $twig = new Environment($loader); + $test = new TwigTest( 'odd', null, - ['node_class' => \Twig\Node\Expression\Test\OddTest::class]); + ['node_class' => OddTestExpression::class]); $twig->addTest($test); - class Twig_Node_Expression_Test_Odd extends \Twig\Node\Expression\TestExpression + class OddTestExpression extends TestExpression { public function compile(\Twig\Compiler $compiler) { $compiler ->raw('(') ->subcompile($this->getNode('node')) - ->raw(' % 2 == 1') + ->raw(' % 2 != 0') ->raw(')') ; } @@ -359,6 +365,7 @@ tests also have access to the ``arguments`` node. This node will contain the various other arguments that have been provided to your test. .. versionadded:: 2.6 + Dynamic tests support was added in Twig 2.6. If you want to pass a variable number of positional or named arguments to the @@ -907,6 +914,5 @@ Testing the node visitors can be complex, so extend your test cases from ``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository `tests/Twig/Node`_ directory. -.. _`rot13`: https://secure.php.net/manual/en/function.str-rot13.php .. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/2.x/tests/Fixtures .. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/2.x/tests/Node diff --git a/vendor/twig/twig/doc/api.rst b/vendor/twig/twig/doc/api.rst index 983ef1981..73f8f5dbc 100644 --- a/vendor/twig/twig/doc/api.rst +++ b/vendor/twig/twig/doc/api.rst @@ -138,10 +138,7 @@ Compilation Cache ~~~~~~~~~~~~~~~~~ All template loaders can cache the compiled templates on the filesystem for -future reuse. It speeds up Twig a lot as templates are only compiled once; and -the performance boost is even larger if you use a PHP accelerator such as -OPCache. See the ``cache`` and ``auto_reload`` options of ``\Twig\Environment`` -above for more information. +future reuse. It speeds up Twig a lot as templates are only compiled once. Built-in Loaders ~~~~~~~~~~~~~~~~ @@ -324,12 +321,12 @@ Twig comes bundled with the following extensions: * *Twig\Extension\SandboxExtension*: Adds a sandbox mode to the default Twig environment, making it safe to evaluate untrusted code. -* *Twig\Extension\ProfilerExtension*: Enabled the built-in Twig profiler. +* *Twig\Extension\ProfilerExtension*: Enables the built-in Twig profiler. * *Twig\Extension\OptimizerExtension*: Optimizes the node tree before compilation. -* *Twig\Extension\StringLoaderExtension*: Defined the ``template_from_string`` +* *Twig\Extension\StringLoaderExtension*: Defines the ``template_from_string`` function to allow loading templates from string in a template. The Core, Escaper, and Optimizer extensions are registered by default. @@ -392,26 +389,26 @@ The escaping rules are implemented as follows: * Literals (integers, booleans, arrays, ...) used in the template directly as variables or filter arguments are never automatically escaped: - .. code-block:: twig + .. code-block:: html+twig - {{ "Twig
    " }} {# won't be escaped #} + {{ "Twig
    " }} {# won't be escaped #} - {% set text = "Twig
    " %} + {% set text = "Twig
    " %} {{ text }} {# will be escaped #} * Expressions which the result is a literal or a variable marked safe are never automatically escaped: - .. code-block:: twig + .. code-block:: html+twig - {{ foo ? "Twig
    " : "
    Twig" }} {# won't be escaped #} + {{ foo ? "Twig
    " : "
    Twig" }} {# won't be escaped #} - {% set text = "Twig
    " %} - {{ true ? text : "
    Twig" }} {# will be escaped #} - {{ false ? text : "
    Twig" }} {# won't be escaped #} + {% set text = "Twig
    " %} + {{ true ? text : "
    Twig" }} {# will be escaped #} + {{ false ? text : "
    Twig" }} {# won't be escaped #} - {% set text = "Twig
    " %} - {{ foo ? text|raw : "
    Twig" }} {# won't be escaped #} + {% set text = "Twig
    " %} + {{ foo ? text|raw : "
    Twig" }} {# won't be escaped #} * Objects with a ``__toString`` method are converted to strings and escaped. You can mark some classes and/or interfaces as being safe for some diff --git a/vendor/twig/twig/doc/deprecated.rst b/vendor/twig/twig/doc/deprecated.rst index d7a6145ed..451270371 100644 --- a/vendor/twig/twig/doc/deprecated.rst +++ b/vendor/twig/twig/doc/deprecated.rst @@ -21,9 +21,9 @@ Inheritance Errors ------ - * Passing a string as the ``$source`` argument on ``\Twig\Error\Error`` / - ``Twig\Error\Error`` constructor is deprecated since Twig 2.6.1. Pass an - instance of ``Twig\Source`` instead. +* Passing a string as the ``$source`` argument on ``\Twig\Error\Error`` / + ``Twig\Error\Error`` constructor is deprecated since Twig 2.6.1. Pass an + instance of ``Twig\Source`` instead. Tags ---- @@ -41,7 +41,7 @@ Tags * Adding an ``if`` condition on a ``for`` tag is deprecated in Twig 2.10. Use a ``filter`` filter or an "if" condition inside the "for" body instead (if your condition - depends on a variable updated inside the loop) + depends on a variable updated inside the loop). Final Classes ------------- diff --git a/vendor/twig/twig/doc/filters/batch.rst b/vendor/twig/twig/doc/filters/batch.rst index 7d331499d..f8f14015c 100644 --- a/vendor/twig/twig/doc/filters/batch.rst +++ b/vendor/twig/twig/doc/filters/batch.rst @@ -5,9 +5,9 @@ The ``batch`` filter "batches" items by returning a list of lists with the given number of items. A second parameter can be provided and used to fill in missing items: -.. code-block:: twig +.. code-block:: html+twig - {% set items = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] %} + {% set items = ['a', 'b', 'c', 'd'] %} {% for row in items|batch(3, 'No item') %} @@ -21,7 +21,7 @@ missing items: The above example will be rendered as: -.. code-block:: twig +.. code-block:: html+twig
    @@ -31,11 +31,6 @@ The above example will be rendered as: - - - - - diff --git a/vendor/twig/twig/doc/filters/column.rst b/vendor/twig/twig/doc/filters/column.rst index 97a3037dc..6808167b1 100644 --- a/vendor/twig/twig/doc/filters/column.rst +++ b/vendor/twig/twig/doc/filters/column.rst @@ -2,6 +2,7 @@ ========== .. versionadded:: 2.8 + The ``column`` filter was added in Twig 2.8. The ``column`` filter returns the values from a single column in the input diff --git a/vendor/twig/twig/doc/filters/country_name.rst b/vendor/twig/twig/doc/filters/country_name.rst index 7e267f12f..f8ebbaf7b 100644 --- a/vendor/twig/twig/doc/filters/country_name.rst +++ b/vendor/twig/twig/doc/filters/country_name.rst @@ -2,6 +2,7 @@ ================ .. versionadded:: 2.12 + The ``country_name`` filter was added in Twig 2.12. The ``country_name`` filter returns the country name given its ISO-3166 @@ -26,10 +27,10 @@ By default, the filter uses the current locale. You can pass it explicitly: .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/filters/currency_name.rst b/vendor/twig/twig/doc/filters/currency_name.rst index a665e4b6f..2b48107f0 100644 --- a/vendor/twig/twig/doc/filters/currency_name.rst +++ b/vendor/twig/twig/doc/filters/currency_name.rst @@ -2,6 +2,7 @@ ================= .. versionadded:: 2.12 + The ``currency_name`` filter was added in Twig 2.12. The ``currency_name`` filter returns the currency name given its three-letter @@ -29,10 +30,10 @@ By default, the filter uses the current locale. You can pass it explicitly: .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/filters/currency_symbol.rst b/vendor/twig/twig/doc/filters/currency_symbol.rst index 8d533c991..4cb60feb4 100644 --- a/vendor/twig/twig/doc/filters/currency_symbol.rst +++ b/vendor/twig/twig/doc/filters/currency_symbol.rst @@ -2,6 +2,7 @@ =================== .. versionadded:: 2.12 + The ``currency_symbol`` filter was added in Twig 2.12. The ``currency_symbol`` filter returns the currency symbol given its three-letter @@ -29,10 +30,10 @@ By default, the filter uses the current locale. You can pass it explicitly: .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/filters/data_uri.rst b/vendor/twig/twig/doc/filters/data_uri.rst index fa5a81ed3..afbf4e2fe 100644 --- a/vendor/twig/twig/doc/filters/data_uri.rst +++ b/vendor/twig/twig/doc/filters/data_uri.rst @@ -2,12 +2,13 @@ ============ .. versionadded:: 2.12 + The ``data_uri`` filter was added in Twig 2.12. The ``data_uri`` filter generates a URL using the data scheme as defined in RFC 2397: -.. code-block:: twig +.. code-block:: html+twig {{ image_data|data_uri }} @@ -29,10 +30,10 @@ The ``data_uri`` filter generates a URL using the data scheme as defined in RFC .. code-block:: bash - $ composer req twig/html-extra + $ composer require twig/html-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Html\HtmlExtension; diff --git a/vendor/twig/twig/doc/filters/date.rst b/vendor/twig/twig/doc/filters/date.rst index 95a1cbff2..ec08d5563 100644 --- a/vendor/twig/twig/doc/filters/date.rst +++ b/vendor/twig/twig/doc/filters/date.rst @@ -37,9 +37,7 @@ date, use a ternary operator: If no format is provided, Twig will use the default one: ``F j, Y H:i``. This default can be changed by calling the ``setDateFormat()`` method on the ``core`` extension instance. The first argument is the default format for -dates and the second one is the default format for date intervals: - -.. code-block:: php +dates and the second one is the default format for date intervals:: $twig = new \Twig\Environment($loader); $twig->getExtension(\Twig\Extension\CoreExtension::class)->setDateFormat('d/m/Y', '%d days'); @@ -62,9 +60,7 @@ timezone, pass ``false`` as the timezone value: {{ post.published_at|date("m/d/Y", false) }} -The default timezone can also be set globally by calling ``setTimezone()``: - -.. code-block:: php +The default timezone can also be set globally by calling ``setTimezone()``:: $twig = new \Twig\Environment($loader); $twig->getExtension(\Twig\Extension\CoreExtension::class)->setTimezone('Europe/Paris'); diff --git a/vendor/twig/twig/doc/filters/default.rst b/vendor/twig/twig/doc/filters/default.rst index c4ccb56a5..2376fe7a6 100644 --- a/vendor/twig/twig/doc/filters/default.rst +++ b/vendor/twig/twig/doc/filters/default.rst @@ -21,6 +21,15 @@ undefined: .. code-block:: twig {{ var.method(foo|default('foo'))|default('foo') }} + +Using the ``default`` filter on a boolean variable might trigger unexpected behavior, as +``false`` is treated as an empty value. Consider using ``??`` instead: + +.. code-block:: twig + + {% set foo = false %} + {{ foo|default(true) }} {# true #} + {{ foo ?? true }} {# false #} .. note:: diff --git a/vendor/twig/twig/doc/filters/escape.rst b/vendor/twig/twig/doc/filters/escape.rst index 7c654ab60..f105d97a3 100644 --- a/vendor/twig/twig/doc/filters/escape.rst +++ b/vendor/twig/twig/doc/filters/escape.rst @@ -94,13 +94,11 @@ Custom Escapers --------------- You can define custom escapers by calling the ``setEscaper()`` method on the -``core`` extension instance. The first argument is the escaper name (to be -used in the ``escape`` call) and the second one must be a valid PHP callable: - -.. code-block:: php +escaper extension instance. The first argument is the escaper name (to be +used in the ``escape`` call) and the second one must be a valid PHP callable:: $twig = new \Twig\Environment($loader); - $twig->getExtension(\Twig\Extension\CoreExtension::class)->setEscaper('csv', 'csv_escaper'); + $twig->getExtension(\Twig\Extension\EscaperExtension::class)->setEscaper('csv', 'csv_escaper'); When called by Twig, the callable receives the Twig environment instance, the string to escape, and the charset. diff --git a/vendor/twig/twig/doc/filters/filter.rst b/vendor/twig/twig/doc/filters/filter.rst index e9f968290..c502c30d5 100644 --- a/vendor/twig/twig/doc/filters/filter.rst +++ b/vendor/twig/twig/doc/filters/filter.rst @@ -1,8 +1,9 @@ ``filter`` ========== -.. versionadded:: 1.41 - The ``filter`` filter was added in Twig 1.41 and 2.10. +.. versionadded:: 2.10 + + The ``filter`` filter was added in Twig 2.10. The ``filter`` filter filters elements of a sequence or a mapping using an arrow function. The arrow function receives the value of the sequence or mapping: diff --git a/vendor/twig/twig/doc/filters/format.rst b/vendor/twig/twig/doc/filters/format.rst index c0c96ee3f..00c09bd7e 100644 --- a/vendor/twig/twig/doc/filters/format.rst +++ b/vendor/twig/twig/doc/filters/format.rst @@ -13,4 +13,6 @@ The ``format`` filter formats a given string by replacing the placeholders .. _`sprintf`: https://secure.php.net/sprintf -.. seealso:: :doc:`replace` +.. seealso:: + + :doc:`replace` diff --git a/vendor/twig/twig/doc/filters/format_currency.rst b/vendor/twig/twig/doc/filters/format_currency.rst index 8be71ac0f..9c254a91a 100644 --- a/vendor/twig/twig/doc/filters/format_currency.rst +++ b/vendor/twig/twig/doc/filters/format_currency.rst @@ -2,6 +2,7 @@ =================== .. versionadded:: 2.12 + The ``format_currency`` filter was added in Twig 2.12. The ``format_currency`` filter formats a number as a currency: @@ -57,10 +58,10 @@ By default, the filter uses the current locale. You can pass it explicitly: .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/filters/format_date.rst b/vendor/twig/twig/doc/filters/format_date.rst index 39c80949b..1fa1a9147 100644 --- a/vendor/twig/twig/doc/filters/format_date.rst +++ b/vendor/twig/twig/doc/filters/format_date.rst @@ -2,10 +2,11 @@ =============== .. versionadded:: 2.12 + The ``format_date`` filter was added in Twig 2.12. The ``format_date`` filter formats a date. It behaves in the exact same way as -the ``format_datetime`` filter, but without the time. +the :doc:`format_datetime` filter, but without the time. .. note:: @@ -14,10 +15,10 @@ the ``format_datetime`` filter, but without the time. .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/filters/format_datetime.rst b/vendor/twig/twig/doc/filters/format_datetime.rst index aba69e740..8dc6381e2 100644 --- a/vendor/twig/twig/doc/filters/format_datetime.rst +++ b/vendor/twig/twig/doc/filters/format_datetime.rst @@ -2,12 +2,11 @@ =================== .. versionadded:: 2.12 + The ``format_datetime`` filter was added in Twig 2.12. The ``format_datetime`` filter formats a date time: - public function formatDateTime(Environment $env, $date, ?string $dateFormat = 'medium', ?string $timeFormat = 'medium', string $pattern = '', $timezone = null, string $calendar = 'gregorian', string $locale = null): string - .. code-block:: twig {# Aug 7, 2019, 11:39:12 PM #} @@ -28,7 +27,10 @@ You can tweak the output for the date part and the time part: Supported values are: ``none``, ``short``, ``medium``, ``long``, and ``full``. -For greater flexiblity, you can even define your own pattern: +For greater flexiblity, you can even define your own pattern (see the `ICU user +guide +`_ +for supported patterns). .. code-block:: twig @@ -49,10 +51,10 @@ By default, the filter uses the current locale. You can pass it explicitly: .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/filters/format_number.rst b/vendor/twig/twig/doc/filters/format_number.rst index b8a9a0ffc..7864f081d 100644 --- a/vendor/twig/twig/doc/filters/format_number.rst +++ b/vendor/twig/twig/doc/filters/format_number.rst @@ -2,6 +2,7 @@ ================= .. versionadded:: 2.12 + The ``format_number`` filter was added in Twig 2.12. The ``format_number`` filter formats a number: @@ -80,11 +81,8 @@ You can pass attributes to tweak the output: .. code-block:: twig - {# €12.34 #} - {{ '12.345'|format_number('EUR', {rounding_mode: 'floor'}) }} - - {# €1,000,000.0000 #} - {{ '1000000'|format_number('EUR', {fraction_digit: 4}) }} + {# 12.3% #} + {{ '0.12345'|format_percent_number({rounding_mode: 'floor', fraction_digit: 1}) }} By default, the filter uses the current locale. You can pass it explicitly: @@ -100,10 +98,10 @@ By default, the filter uses the current locale. You can pass it explicitly: .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/filters/format_time.rst b/vendor/twig/twig/doc/filters/format_time.rst index e46e246bb..606078308 100644 --- a/vendor/twig/twig/doc/filters/format_time.rst +++ b/vendor/twig/twig/doc/filters/format_time.rst @@ -2,10 +2,11 @@ =============== .. versionadded:: 2.12 + The ``format_time`` filter was added in Twig 2.12. The ``format_time`` filter formats a time. It behaves in the exact same way as -the ``format_datetime`` filter, but without the date. +the :doc:`format_datetime` filter, but without the date. .. note:: @@ -14,10 +15,10 @@ the ``format_datetime`` filter, but without the date. .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/filters/html_to_markdown.rst b/vendor/twig/twig/doc/filters/html_to_markdown.rst index b60327197..d382724e4 100644 --- a/vendor/twig/twig/doc/filters/html_to_markdown.rst +++ b/vendor/twig/twig/doc/filters/html_to_markdown.rst @@ -2,11 +2,12 @@ ==================== .. versionadded:: 2.12 + The ``html_to_markdown`` filter was added in Twig 2.12. The ``html_to_markdown`` filter converts a block of HTML to Markdown: -.. code-block:: twig +.. code-block:: html+twig {% apply html_to_markdown %} @@ -14,21 +15,7 @@ The ``html_to_markdown`` filter converts a block of HTML to Markdown: {% endapply %} -You can also add some options by passing them as an argument to the filter: - -.. code-block:: twig - - {% apply html_to_markdown({hard_break: false}) %} - -

    Hello!

    - - {% endapply %} - -.. note:: - - The options are the ones provided by the ``league/html-to-markdown`` package. - -You can also use the filter on an included file: +You can also use the filter on an entire template which you ``include``: .. code-block:: twig @@ -41,12 +28,18 @@ You can also use the filter on an included file: .. code-block:: bash - $ composer req twig/markdown-extra + $ composer require twig/markdown-extra - Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + On Symfony projects, you can automatically enable it by installing the + ``twig/extra-bundle``: - use Twig\Extra\Markdown\MarkdownMarkdownExtension; + .. code-block:: bash + + $ composer require twig/extra-bundle + + Or add the extension explicitly on the Twig environment:: + + use Twig\Extra\Markdown\MarkdownExtension; $twig = new \Twig\Environment(...); $twig->addExtension(new MarkdownExtension()); @@ -64,3 +57,22 @@ You can also use the filter on an included file: } } }); + +``html_to_markdown`` is just a frontend; the actual conversion is done by one of +the following compatible libraries, from which you can choose: + +* [erusev/parsedown](https://github.com/erusev/parsedown) +* [thephpleague/html-to-markdown](https://github.com/thephpleague/html-to-markdown) +* [michelf/php-markdown](https://github.com/michelf/php-markdown) + +Depending on the library, you can also add some options by passing them as an argument +to the filter. Example for ``league/html-to-markdown``: + +.. code-block:: html+twig + + {% apply html_to_markdown({hard_break: false}) %} + +

    Hello!

    + + {% endapply %} + diff --git a/vendor/twig/twig/doc/filters/index.rst b/vendor/twig/twig/doc/filters/index.rst index a35c3d76d..eea2383e5 100644 --- a/vendor/twig/twig/doc/filters/index.rst +++ b/vendor/twig/twig/doc/filters/index.rst @@ -47,6 +47,7 @@ Filters reverse round slice + slug sort spaceless split diff --git a/vendor/twig/twig/doc/filters/inky_to_html.rst b/vendor/twig/twig/doc/filters/inky_to_html.rst index 5462b572d..8a6691650 100644 --- a/vendor/twig/twig/doc/filters/inky_to_html.rst +++ b/vendor/twig/twig/doc/filters/inky_to_html.rst @@ -2,12 +2,13 @@ ================ .. versionadded:: 2.12 + The ``inky_to_html`` filter was added in Twig 2.12. The ``inky_to_html`` filter processes an `inky email template `_: -.. code-block:: twig +.. code-block:: html+twig {% apply inky_to_html %} @@ -29,10 +30,10 @@ You can also use the filter on an included file: .. code-block:: bash - $ composer req twig/inky-extra + $ composer require twig/inky-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Inky\InkyExtension; diff --git a/vendor/twig/twig/doc/filters/inline_css.rst b/vendor/twig/twig/doc/filters/inline_css.rst index d0f75c966..3da6fd95e 100644 --- a/vendor/twig/twig/doc/filters/inline_css.rst +++ b/vendor/twig/twig/doc/filters/inline_css.rst @@ -2,11 +2,12 @@ ============== .. versionadded:: 2.12 + The ``inline_css`` filter was added in Twig 2.12. The ``inline_css`` filter inline CSS styles in HTML documents: -.. code-block:: twig +.. code-block:: html+twig {% apply inline_css %} @@ -23,7 +24,7 @@ The ``inline_css`` filter inline CSS styles in HTML documents: You can also add some stylesheets by passing them as arguments to the filter: -.. code-block:: twig +.. code-block:: html+twig {% apply inline_css(source("some_styles.css"), source("another.css")) %} @@ -53,10 +54,10 @@ Note that the CSS inliner works on an entire HTML document, not a fragment. .. code-block:: bash - $ composer req twig/cssinliner-extra + $ composer require twig/cssinliner-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\CssInliner\CssInlinerExtension; diff --git a/vendor/twig/twig/doc/filters/join.rst b/vendor/twig/twig/doc/filters/join.rst index a9ea147e4..ed8d01ec4 100644 --- a/vendor/twig/twig/doc/filters/join.rst +++ b/vendor/twig/twig/doc/filters/join.rst @@ -2,6 +2,7 @@ ======== .. versionadded:: 2.6.1 + The ``and`` argument was added in Twig 2.6.1. The ``join`` filter returns a string which is the concatenation of the items diff --git a/vendor/twig/twig/doc/filters/language_name.rst b/vendor/twig/twig/doc/filters/language_name.rst index ca9b00d38..5e21a048a 100644 --- a/vendor/twig/twig/doc/filters/language_name.rst +++ b/vendor/twig/twig/doc/filters/language_name.rst @@ -2,6 +2,7 @@ ================= .. versionadded:: 2.12 + The ``language_name`` filter was added in Twig 2.12. The ``language_name`` filter returns the language name given its two-letter @@ -29,10 +30,10 @@ By default, the filter uses the current locale. You can pass it explicitly: .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/filters/length.rst b/vendor/twig/twig/doc/filters/length.rst index 3ea6d1a65..a696b0d18 100644 --- a/vendor/twig/twig/doc/filters/length.rst +++ b/vendor/twig/twig/doc/filters/length.rst @@ -14,7 +14,7 @@ return value of the ``count()`` method. For objects that implement the ``__toString()`` magic method (and not ``Countable``), it will return the length of the string provided by that method. -For objects that implement the ``IteratorAggregate`` interface, ``length`` will use the return value of the ``iterator_count()`` method. +For objects that implement the ``Traversable`` interface, ``length`` will use the return value of the ``iterator_count()`` method. .. code-block:: twig diff --git a/vendor/twig/twig/doc/filters/locale_name.rst b/vendor/twig/twig/doc/filters/locale_name.rst index d5ecc1a0e..24c3e130c 100644 --- a/vendor/twig/twig/doc/filters/locale_name.rst +++ b/vendor/twig/twig/doc/filters/locale_name.rst @@ -2,6 +2,7 @@ =============== .. versionadded:: 2.12 + The ``locale_name`` filter was added in Twig 2.12. The ``locale_name`` filter returns the locale name given its two-letter @@ -29,10 +30,10 @@ By default, the filter uses the current locale. You can pass it explicitly: .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/filters/map.rst b/vendor/twig/twig/doc/filters/map.rst index e983e33b4..a2ff2a8f8 100644 --- a/vendor/twig/twig/doc/filters/map.rst +++ b/vendor/twig/twig/doc/filters/map.rst @@ -1,8 +1,9 @@ ``map`` ======= -.. versionadded:: 1.41 - The ``map`` filter was added in Twig 1.41 and 2.10. +.. versionadded:: 2.10 + + The ``map`` filter was added in Twig 2.10. The ``map`` filter applies an arrow function to the elements of a sequence or a mapping. The arrow function receives the value of the sequence or mapping: diff --git a/vendor/twig/twig/doc/filters/markdown_to_html.rst b/vendor/twig/twig/doc/filters/markdown_to_html.rst index 8e515be80..179d29ec5 100644 --- a/vendor/twig/twig/doc/filters/markdown_to_html.rst +++ b/vendor/twig/twig/doc/filters/markdown_to_html.rst @@ -2,6 +2,7 @@ ==================== .. versionadded:: 2.12 + The ``markdown_to_html`` filter was added in Twig 2.12. The ``markdown_to_html`` filter converts a block of Markdown to HTML: @@ -27,11 +28,13 @@ removed consistently before conversion: Hello! {% endapply %} -You can also use the filter on an included file: +You can also use the filter on an included file or a variable: .. code-block:: twig {{ include('some_template.markdown.twig')|markdown_to_html }} + + {{ changelog|markdown_to_html }} .. note:: @@ -40,12 +43,12 @@ You can also use the filter on an included file: .. code-block:: bash - $ composer req twig/markdown-extra + $ composer require twig/markdown-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: - use Twig\Extra\Markdown\MarkdownMarkdownExtension; + use Twig\Extra\Markdown\MarkdownExtension; $twig = new \Twig\Environment(...); $twig->addExtension(new MarkdownExtension()); @@ -63,3 +66,6 @@ You can also use the filter on an included file: } } }); + + Afterwards you need to install a markdown library of your choice. Some of them are + mentioned in the ``require-dev`` section of the ``twig/markdown-extra`` package. diff --git a/vendor/twig/twig/doc/filters/nl2br.rst b/vendor/twig/twig/doc/filters/nl2br.rst index 1eefb04aa..7c84c22db 100644 --- a/vendor/twig/twig/doc/filters/nl2br.rst +++ b/vendor/twig/twig/doc/filters/nl2br.rst @@ -3,7 +3,7 @@ The ``nl2br`` filter inserts HTML line breaks before all newlines in a string: -.. code-block:: twig +.. code-block:: html+twig {{ "I like Twig.\nYou will like it too."|nl2br }} {# outputs diff --git a/vendor/twig/twig/doc/filters/number_format.rst b/vendor/twig/twig/doc/filters/number_format.rst index 9ee0c6d7f..c44e2e353 100644 --- a/vendor/twig/twig/doc/filters/number_format.rst +++ b/vendor/twig/twig/doc/filters/number_format.rst @@ -33,9 +33,7 @@ options of: * ``.`` as the decimal point. * ``,`` as the thousands separator. -These defaults can be changed through the core extension: - -.. code-block:: php +These defaults can be changed through the core extension:: $twig = new \Twig\Environment($loader); $twig->getExtension(\Twig\Extension\CoreExtension::class)->setNumberFormat(3, '.', ','); diff --git a/vendor/twig/twig/doc/filters/raw.rst b/vendor/twig/twig/doc/filters/raw.rst index ad74a52ae..243037a98 100644 --- a/vendor/twig/twig/doc/filters/raw.rst +++ b/vendor/twig/twig/doc/filters/raw.rst @@ -17,7 +17,7 @@ if ``raw`` is the last filter applied to it: Be careful when using the ``raw`` filter inside expressions: - .. code-block:: twig + .. code-block:: html+twig {% autoescape %} {% set hello = 'Hello' %} diff --git a/vendor/twig/twig/doc/filters/reduce.rst b/vendor/twig/twig/doc/filters/reduce.rst index af6164a95..e8adf4d33 100644 --- a/vendor/twig/twig/doc/filters/reduce.rst +++ b/vendor/twig/twig/doc/filters/reduce.rst @@ -1,8 +1,9 @@ ``reduce`` ========== -.. versionadded:: 1.41 - The ``reduce`` filter was added in Twig 1.41 and 2.10. +.. versionadded:: 2.10 + + The ``reduce`` filter was added in Twig 2.10. The ``reduce`` filter iteratively reduces a sequence or a mapping to a single value using an arrow function, so as to reduce it to a single value. The arrow diff --git a/vendor/twig/twig/doc/filters/replace.rst b/vendor/twig/twig/doc/filters/replace.rst index ceb6c0097..5761a2196 100644 --- a/vendor/twig/twig/doc/filters/replace.rst +++ b/vendor/twig/twig/doc/filters/replace.rst @@ -22,4 +22,6 @@ Arguments * ``from``: The placeholder values -.. seealso:: :doc:`format` +.. seealso:: + + :doc:`format` diff --git a/vendor/twig/twig/doc/filters/slug.rst b/vendor/twig/twig/doc/filters/slug.rst new file mode 100644 index 000000000..99cfa173e --- /dev/null +++ b/vendor/twig/twig/doc/filters/slug.rst @@ -0,0 +1,37 @@ +``slug`` +======== + +The ``slug`` filter transforms a given string into another string that +only includes safe ASCII characters. + +Here is an example: + +.. code-block:: twig + + {{ 'Wôrķšƥáçè ~~sèťtïñğš~~'|slug }} + Workspace-settings + +The default separator between words is a dash (``-``), but you can +define a selector of your choice by passing it as an argument: + +.. code-block:: twig + + {{ 'Wôrķšƥáçè ~~sèťtïñğš~~'|slug('/') }} + Workspace/settings + +The slugger automatically detects the language of the original +string, but you can also specify it explicitly using the second +argument: + +.. code-block:: twig + + {{ '...'|slug('-', 'ko') }} + +The ``slug`` filter uses the method by the same name in Symfony's +`AsciiSlugger `_. + +Arguments +--------- + +* ``separator``: The separator that is used to join words (defaults to ``-``) +* ``locale``: The locale of the original string (if none is specified, it will be automatically detected) diff --git a/vendor/twig/twig/doc/filters/sort.rst b/vendor/twig/twig/doc/filters/sort.rst index 1df70ffdb..46ac5c3fc 100644 --- a/vendor/twig/twig/doc/filters/sort.rst +++ b/vendor/twig/twig/doc/filters/sort.rst @@ -2,6 +2,7 @@ ======== .. versionadded:: 2.12 + The ``arrow`` argument was added in Twig 2.12. The ``sort`` filter sorts an array: @@ -20,7 +21,7 @@ The ``sort`` filter sorts an array: You can pass an arrow function to sort the array: -.. code-block:: twig +.. code-block:: html+twig {% set fruits = [ { name: 'Apples', quantity: 5 }, diff --git a/vendor/twig/twig/doc/filters/spaceless.rst b/vendor/twig/twig/doc/filters/spaceless.rst index 17966a819..bafd5a047 100644 --- a/vendor/twig/twig/doc/filters/spaceless.rst +++ b/vendor/twig/twig/doc/filters/spaceless.rst @@ -1,14 +1,14 @@ ``spaceless`` ============= -.. versionadded:: 1.38 +.. versionadded:: 2.7 - The ``spaceless`` filter was added in Twig 1.38. + The ``spaceless`` filter was added in Twig 2.7. Use the ``spaceless`` filter to remove whitespace *between HTML tags*, not whitespace within HTML tags or whitespace in plain text: -.. code-block:: twig +.. code-block:: html+twig {{ "
    @@ -21,7 +21,7 @@ whitespace within HTML tags or whitespace in plain text: You can combine ``spaceless`` with the ``apply`` tag to apply the transformation on large amounts of HTML: -.. code-block:: twig +.. code-block:: html+twig {% apply spaceless %}
    diff --git a/vendor/twig/twig/doc/filters/striptags.rst b/vendor/twig/twig/doc/filters/striptags.rst index 62b2a7b3c..7a0aabddc 100644 --- a/vendor/twig/twig/doc/filters/striptags.rst +++ b/vendor/twig/twig/doc/filters/striptags.rst @@ -10,7 +10,7 @@ by one space: You can also provide tags which should not be stripped: -.. code-block:: twig +.. code-block:: html+twig {{ some_html|striptags('

    ') }} diff --git a/vendor/twig/twig/doc/filters/timezone_name.rst b/vendor/twig/twig/doc/filters/timezone_name.rst index e42cf28b4..dc64eca5d 100644 --- a/vendor/twig/twig/doc/filters/timezone_name.rst +++ b/vendor/twig/twig/doc/filters/timezone_name.rst @@ -2,6 +2,7 @@ ================= .. versionadded:: 2.12 + The ``timezone_name`` filter was added in Twig 2.12. The ``timezone_name`` filter returns the timezone name given a timezone identifier: @@ -28,10 +29,10 @@ By default, the filter uses the current locale. You can pass it explicitly: .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/filters/u.rst b/vendor/twig/twig/doc/filters/u.rst index d0b787633..1adf83c00 100644 --- a/vendor/twig/twig/doc/filters/u.rst +++ b/vendor/twig/twig/doc/filters/u.rst @@ -2,6 +2,7 @@ ===== .. versionadded:: 2.12.1 + The ``u`` filter was added in Twig 2.12.1. The ``u`` filter wraps a text in a Unicode object (a `Symfony UnicodeString @@ -31,6 +32,13 @@ Truncating a string: {{ 'Lorem ipsum'|u.truncate(8, '...') }} Lorem... +The ``truncate`` method also accepts a third argument to preserve whole words: + +.. code-block:: twig + + {{ 'Lorem ipsum dolor'|u.truncate(10, '...', false) }} + Lorem ipsum... + Converting a string to *snake* case or *camelCase*: .. code-block:: twig @@ -67,7 +75,7 @@ For large strings manipulation, use the ``apply`` tag: .. code-block:: bash - $ composer req twig/string-extra + $ composer require twig/string-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension explicitly on the Twig environment:: diff --git a/vendor/twig/twig/doc/filters/url_encode.rst b/vendor/twig/twig/doc/filters/url_encode.rst index 50a44e5d6..60cf365f1 100644 --- a/vendor/twig/twig/doc/filters/url_encode.rst +++ b/vendor/twig/twig/doc/filters/url_encode.rst @@ -17,6 +17,7 @@ or an array as query string: .. note:: - Internally, Twig uses the PHP ``rawurlencode``. + Internally, Twig uses the PHP `rawurlencode`_ or the `http_build_query`_ function. .. _`rawurlencode`: https://secure.php.net/rawurlencode +.. _`http_build_query`: https://secure.php.net/http_build_query diff --git a/vendor/twig/twig/doc/functions/block.rst b/vendor/twig/twig/doc/functions/block.rst index 011843203..117e160f5 100644 --- a/vendor/twig/twig/doc/functions/block.rst +++ b/vendor/twig/twig/doc/functions/block.rst @@ -4,7 +4,7 @@ When a template uses inheritance and if you want to print a block multiple times, use the ``block`` function: -.. code-block:: twig +.. code-block:: html+twig {% block title %}{% endblock %} @@ -32,4 +32,6 @@ current template: ... {% endif %} -.. seealso:: :doc:`extends<../tags/extends>`, :doc:`parent<../functions/parent>` +.. seealso:: + + :doc:`extends<../tags/extends>`, :doc:`parent<../functions/parent>` diff --git a/vendor/twig/twig/doc/functions/country_timezones.rst b/vendor/twig/twig/doc/functions/country_timezones.rst index ff6382523..609584332 100644 --- a/vendor/twig/twig/doc/functions/country_timezones.rst +++ b/vendor/twig/twig/doc/functions/country_timezones.rst @@ -2,6 +2,7 @@ ===================== .. versionadded:: 2.12 + The ``country_timezones`` function was added in Twig 2.12. The ``country_timezones`` function returns the names of the timezones associated @@ -19,10 +20,10 @@ with a given country code: .. code-block:: bash - $ composer req twig/intl-extra + $ composer require twig/intl-extra Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension - explictly on the Twig environment:: + explicitly on the Twig environment:: use Twig\Extra\Intl\IntlExtension; diff --git a/vendor/twig/twig/doc/functions/date.rst b/vendor/twig/twig/doc/functions/date.rst index ee80a4e03..3329a5698 100644 --- a/vendor/twig/twig/doc/functions/date.rst +++ b/vendor/twig/twig/doc/functions/date.rst @@ -3,7 +3,7 @@ Converts an argument to a date to allow date comparison: -.. code-block:: twig +.. code-block:: html+twig {% if date(user.created_at) < date('-2days') %} {# do something #} @@ -13,7 +13,7 @@ The argument must be in one of PHP’s supported `date and time formats`_. You can pass a timezone as the second argument: -.. code-block:: twig +.. code-block:: html+twig {% if date(user.created_at) < date('-2days', 'Europe/Paris') %} {# do something #} @@ -21,7 +21,7 @@ You can pass a timezone as the second argument: If no argument is passed, the function returns the current date: -.. code-block:: twig +.. code-block:: html+twig {% if date(user.created_at) < date() %} {# always! #} @@ -30,9 +30,7 @@ If no argument is passed, the function returns the current date: .. note:: You can set the default timezone globally by calling ``setTimezone()`` on - the ``core`` extension instance: - - .. code-block:: php + the ``core`` extension instance:: $twig = new \Twig\Environment($loader); $twig->getExtension(\Twig\Extension\CoreExtension::class)->setTimezone('Europe/Paris'); diff --git a/vendor/twig/twig/doc/functions/dump.rst b/vendor/twig/twig/doc/functions/dump.rst index b295b875a..c7264edda 100644 --- a/vendor/twig/twig/doc/functions/dump.rst +++ b/vendor/twig/twig/doc/functions/dump.rst @@ -28,7 +28,7 @@ introspecting its variables: In an HTML context, wrap the output with a ``pre`` tag to make it easier to read: -.. code-block:: twig +.. code-block:: html+twig

             {{ dump(user) }}
    diff --git a/vendor/twig/twig/doc/functions/html_classes.rst b/vendor/twig/twig/doc/functions/html_classes.rst
    index 0bf9d088e..cc6b2d9e3 100644
    --- a/vendor/twig/twig/doc/functions/html_classes.rst
    +++ b/vendor/twig/twig/doc/functions/html_classes.rst
    @@ -2,12 +2,13 @@
     ================
     
     .. versionadded:: 2.12
    +
         The ``html_classes`` function was added in Twig 2.12.
     
     The ``html_classes`` function returns a string by conditionally joining class
     names together:
     
    -.. code-block:: jinja
    +.. code-block:: html+twig
     
         

    `, :doc:`block<../functions/block>`, :doc:`block<../tags/block>` +.. seealso:: + + :doc:`extends<../tags/extends>`, :doc:`block<../functions/block>`, :doc:`block<../tags/block>` diff --git a/vendor/twig/twig/doc/functions/random.rst b/vendor/twig/twig/doc/functions/random.rst index baaaf9629..ed381db53 100644 --- a/vendor/twig/twig/doc/functions/random.rst +++ b/vendor/twig/twig/doc/functions/random.rst @@ -2,6 +2,7 @@ ========== .. versionadded:: 2.7 + The "max" argument was added in Twig 2.7. The ``random`` function returns a random value depending on the supplied @@ -26,5 +27,3 @@ Arguments * ``values``: The values * ``max``: The max value when values is an integer - -.. _`mt_rand`: https://secure.php.net/mt_rand diff --git a/vendor/twig/twig/doc/functions/template_from_string.rst b/vendor/twig/twig/doc/functions/template_from_string.rst index fd61871c1..d3f394e0e 100644 --- a/vendor/twig/twig/doc/functions/template_from_string.rst +++ b/vendor/twig/twig/doc/functions/template_from_string.rst @@ -2,6 +2,7 @@ ======================== .. versionadded:: 2.8 + The name argument was added in Twig 2.8. The ``template_from_string`` function loads a template from a string: diff --git a/vendor/twig/twig/doc/intro.rst b/vendor/twig/twig/doc/intro.rst index c477c7838..de3dc7a8b 100644 --- a/vendor/twig/twig/doc/intro.rst +++ b/vendor/twig/twig/doc/intro.rst @@ -23,10 +23,14 @@ Twig is used by many Open-Source projects like Symfony, Drupal8, eZPublish, phpBB, Matomo, OroCRM; and many frameworks have support for it as well like Slim, Yii, Laravel, and Codeigniter — just to name a few. +.. admonition:: Screencast + + Like to learn from video tutorials? Check out the `SymfonyCasts Twig Tutorial`_! + Prerequisites ------------- -Twig needs at least **PHP 7.0.0** to run. +Twig 2.x needs at least **PHP 7.2.5** to run. Installation ------------ @@ -40,9 +44,7 @@ The recommended way to install Twig is via Composer: Basic API Usage --------------- -This section gives you a brief introduction to the PHP API for Twig. - -.. code-block:: php +This section gives you a brief introduction to the PHP API for Twig:: require_once '/path/to/vendor/autoload.php'; @@ -68,3 +70,5 @@ filesystem loader:: ]); echo $twig->render('index.html', ['name' => 'Fabien']); + +.. _`SymfonyCasts Twig Tutorial`: https://symfonycasts.com/screencast/twig diff --git a/vendor/twig/twig/doc/recipes.rst b/vendor/twig/twig/doc/recipes.rst index 76f81bbd4..0b59cc8d1 100644 --- a/vendor/twig/twig/doc/recipes.rst +++ b/vendor/twig/twig/doc/recipes.rst @@ -299,7 +299,7 @@ Validating the Template Syntax When template code is provided by a third-party (through a web interface for instance), it might be interesting to validate the template syntax before -saving it. If the template code is stored in a `$template` variable, here is +saving it. If the template code is stored in a ``$template`` variable, here is how you can do it:: try { @@ -516,9 +516,7 @@ include in your templates: $interpolateProvider.startSymbol('{[').endSymbol(']}'); }); - * For Twig, change the delimiters via the ``tag_variable`` Lexer option: - - .. code-block:: php + * For Twig, change the delimiters via the ``tag_variable`` Lexer option:: $env->setLexer(new \Twig\Lexer($env, [ 'tag_variable' => ['{[', ']}'], diff --git a/vendor/twig/twig/doc/tags/apply.rst b/vendor/twig/twig/doc/tags/apply.rst index 2c3b00c08..f3ff3aaa0 100644 --- a/vendor/twig/twig/doc/tags/apply.rst +++ b/vendor/twig/twig/doc/tags/apply.rst @@ -2,6 +2,7 @@ ========= .. versionadded:: 2.9 + The ``apply`` tag was added in Twig 2.9. The ``apply`` tag allows you to apply Twig filters on a block of template data: @@ -14,7 +15,7 @@ The ``apply`` tag allows you to apply Twig filters on a block of template data: You can also chain filters and pass arguments to them: -.. code-block:: twig +.. code-block:: html+twig {% apply lower|escape('html') %} SOME TEXT diff --git a/vendor/twig/twig/doc/tags/autoescape.rst b/vendor/twig/twig/doc/tags/autoescape.rst index 520d779d0..8c621d3a8 100644 --- a/vendor/twig/twig/doc/tags/autoescape.rst +++ b/vendor/twig/twig/doc/tags/autoescape.rst @@ -47,7 +47,7 @@ Functions returning template data (like :doc:`macros` and Twig does not escape static expressions: - .. code-block:: twig + .. code-block:: html+twig {% set hello = "Hello" %} {{ hello }} diff --git a/vendor/twig/twig/doc/tags/block.rst b/vendor/twig/twig/doc/tags/block.rst index e38048232..272bc7f34 100644 --- a/vendor/twig/twig/doc/tags/block.rst +++ b/vendor/twig/twig/doc/tags/block.rst @@ -5,7 +5,8 @@ Blocks are used for inheritance and act as placeholders and replacements at the same time. They are documented in detail in the documentation for the :doc:`extends<../tags/extends>` tag. -Block names should consist of alphanumeric characters, and underscores. Dashes -are not permitted. +Block names must consist of alphanumeric characters, and underscores. The first char can't be a digit and dashes are not permitted. -.. seealso:: :doc:`block<../functions/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`, :doc:`extends<../tags/extends>` +.. seealso:: + + :doc:`block<../functions/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`, :doc:`extends<../tags/extends>` diff --git a/vendor/twig/twig/doc/tags/deprecated.rst b/vendor/twig/twig/doc/tags/deprecated.rst index 70b81f811..e0e6f5576 100644 --- a/vendor/twig/twig/doc/tags/deprecated.rst +++ b/vendor/twig/twig/doc/tags/deprecated.rst @@ -2,6 +2,7 @@ ============== .. versionadded:: 2.6 + The ``deprecated`` tag was added in Twig 2.6. Twig generates a deprecation notice (via a call to the ``trigger_error()`` diff --git a/vendor/twig/twig/doc/tags/embed.rst b/vendor/twig/twig/doc/tags/embed.rst index 3ee166698..42e33b195 100644 --- a/vendor/twig/twig/doc/tags/embed.rst +++ b/vendor/twig/twig/doc/tags/embed.rst @@ -1,7 +1,7 @@ ``embed`` ========= -The ``embed`` tag combines the behaviour of :doc:`include` and +The ``embed`` tag combines the behavior of :doc:`include` and :doc:`extends`. It allows you to include another template's contents, just like ``include`` does. But it also allows you to override any block defined inside the @@ -172,4 +172,6 @@ The ``embed`` tag takes the exact same arguments as the ``include`` tag: case, explicitly set the default auto-escaping strategy with the ``autoescape`` tag. -.. seealso:: :doc:`include<../tags/include>` +.. seealso:: + + :doc:`include<../tags/include>` diff --git a/vendor/twig/twig/doc/tags/extends.rst b/vendor/twig/twig/doc/tags/extends.rst index c2076ac59..7f1c1e8c1 100644 --- a/vendor/twig/twig/doc/tags/extends.rst +++ b/vendor/twig/twig/doc/tags/extends.rst @@ -18,7 +18,7 @@ skeleton document: {% block head %} - + {% block title %}{% endblock %} - My Webpage {% endblock %} @@ -43,7 +43,7 @@ Child Template A child template might look like this: -.. code-block:: twig +.. code-block:: html+twig {% extends "base.html" %} @@ -79,7 +79,7 @@ know which one of the blocks' content to use. If you want to print a block multiple times you can however use the ``block`` function: -.. code-block:: twig +.. code-block:: html+twig {% block title %}{% endblock %}

    {{ block('title') }}

    @@ -92,7 +92,7 @@ It's possible to render the contents of the parent block by using the :doc:`parent<../functions/parent>` function. This gives back the results of the parent block: -.. code-block:: twig +.. code-block:: html+twig {% block sidebar %}

    Table Of Contents

    @@ -120,7 +120,7 @@ Block Nesting and Scope Blocks can be nested for more complex layouts. Per default, blocks have access to variables from outer scopes: -.. code-block:: twig +.. code-block:: html+twig {% for item in seq %}
  • {% block loop_item %}{{ item }}{% endblock %}
  • @@ -190,10 +190,9 @@ but it does not interfere in any way with the logic around it. Let's take the following example to illustrate how a block works and more importantly, how it does not work: -.. code-block:: twig +.. code-block:: html+twig {# base.twig #} - {% for post in posts %} {% block post %}

    {{ post.title }}

    @@ -205,10 +204,9 @@ If you render this template, the result would be exactly the same with or without the ``block`` tag. The ``block`` inside the ``for`` loop is just a way to make it overridable by a child template: -.. code-block:: twig +.. code-block:: html+twig {# child.twig #} - {% extends "base.twig" %} {% block post %} @@ -222,7 +220,7 @@ Now, when rendering the child template, the loop is going to use the block defined in the child template instead of the one defined in the base one; the executed template is then equivalent to the following one: -.. code-block:: twig +.. code-block:: html+twig {% for post in posts %}
    @@ -233,7 +231,7 @@ executed template is then equivalent to the following one: Let's take another example: a block included within an ``if`` statement: -.. code-block:: twig +.. code-block:: html+twig {% if posts is empty %} {% block head %} @@ -250,7 +248,7 @@ what will be rendered when the condition is ``true``. If you want the output to be displayed conditionally, use the following instead: -.. code-block:: twig +.. code-block:: html+twig {% block head %} {{ parent() }} @@ -260,4 +258,6 @@ instead: {% endif %} {% endblock head %} -.. seealso:: :doc:`block<../functions/block>`, :doc:`block<../tags/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>` +.. seealso:: + + :doc:`block<../functions/block>`, :doc:`block<../tags/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>` diff --git a/vendor/twig/twig/doc/tags/filter.rst b/vendor/twig/twig/doc/tags/filter.rst index f225fb251..2af56c148 100644 --- a/vendor/twig/twig/doc/tags/filter.rst +++ b/vendor/twig/twig/doc/tags/filter.rst @@ -17,7 +17,7 @@ data. Just wrap the code in the special ``filter`` section: You can also chain filters and pass arguments to them: -.. code-block:: twig +.. code-block:: html+twig {% filter lower|escape('html') %} SOME TEXT diff --git a/vendor/twig/twig/doc/tags/for.rst b/vendor/twig/twig/doc/tags/for.rst index 8e9b4e582..2d6e81ea4 100644 --- a/vendor/twig/twig/doc/tags/for.rst +++ b/vendor/twig/twig/doc/tags/for.rst @@ -4,7 +4,7 @@ Loop over each item in a sequence. For example, to display a list of users provided in a variable called ``users``: -.. code-block:: twig +.. code-block:: html+twig

    Members

      @@ -95,7 +95,7 @@ Unlike in PHP, it's not possible to ``break`` or ``continue`` in a loop. You can however filter the sequence during iteration which allows you to skip items. The following example skips all the users which are not active: -.. code-block:: twig +.. code-block:: html+twig
        {% for user in users if user.active %} @@ -121,7 +121,7 @@ The `else` Clause If no iteration took place because the sequence was empty, you can render a replacement block by using ``else``: -.. code-block:: twig +.. code-block:: html+twig
          {% for user in users %} @@ -137,7 +137,7 @@ Iterating over Keys By default, a loop iterates over the values of the sequence. You can iterate on keys by using the ``keys`` filter: -.. code-block:: twig +.. code-block:: html+twig

          Members

            @@ -151,7 +151,7 @@ Iterating over Keys and Values You can also access both keys and values: -.. code-block:: twig +.. code-block:: html+twig

            Members

              @@ -166,7 +166,7 @@ Iterating over a Subset You might want to iterate over a subset of values. This can be achieved using the :doc:`slice <../filters/slice>` filter: -.. code-block:: twig +.. code-block:: html+twig

              Top Ten Members

                diff --git a/vendor/twig/twig/doc/tags/if.rst b/vendor/twig/twig/doc/tags/if.rst index 2a1610c82..2d7475227 100644 --- a/vendor/twig/twig/doc/tags/if.rst +++ b/vendor/twig/twig/doc/tags/if.rst @@ -6,7 +6,7 @@ The ``if`` statement in Twig is comparable with the if statements of PHP. In the simplest form you can use it to test if an expression evaluates to ``true``: -.. code-block:: twig +.. code-block:: html+twig {% if online == false %}

                Our website is in maintenance mode. Please, come back later.

                @@ -14,7 +14,7 @@ In the simplest form you can use it to test if an expression evaluates to You can also test if an array is not empty: -.. code-block:: twig +.. code-block:: html+twig {% if users %}
                  @@ -31,7 +31,7 @@ You can also test if an array is not empty: You can also use ``not`` to check for values that evaluate to ``false``: -.. code-block:: twig +.. code-block:: html+twig {% if not user.subscribed %}

                  You are not subscribed to our mailing list.

                  @@ -39,7 +39,7 @@ You can also use ``not`` to check for values that evaluate to ``false``: For multiple conditions, ``and`` and ``or`` can be used: -.. code-block:: twig +.. code-block:: html+twig {% if temperature > 18 and temperature < 27 %}

                  It's a nice day for a walk in the park.

                  diff --git a/vendor/twig/twig/doc/tags/include.rst b/vendor/twig/twig/doc/tags/include.rst index 93ec894da..0882cc676 100644 --- a/vendor/twig/twig/doc/tags/include.rst +++ b/vendor/twig/twig/doc/tags/include.rst @@ -1,7 +1,7 @@ ``include`` =========== -The ``include`` statement includes a template and returns the rendered content +The ``include`` statement includes a template and outputs the rendered content of that file: .. code-block:: twig @@ -31,10 +31,10 @@ of that file: {# vs #} {% set content = include('template.html') %} - {# Filter a rendered template #} - {% filter upper %} + {# Apply filter on a rendered template #} + {% apply upper %} {% include 'template.html' %} - {% endfilter %} + {% endapply %} {# vs #} {{ include('template.html')|upper }} diff --git a/vendor/twig/twig/doc/tags/macro.rst b/vendor/twig/twig/doc/tags/macro.rst index aa40acbbc..cd60117ad 100644 --- a/vendor/twig/twig/doc/tags/macro.rst +++ b/vendor/twig/twig/doc/tags/macro.rst @@ -9,10 +9,10 @@ Macros are defined in regular templates. Imagine having a generic helper template that define how to render HTML forms via macros (called ``forms.html``): -.. code-block:: twig +.. code-block:: html+twig {% macro input(name, value, type = "text", size = 20) %} - + {% endmacro %} {% macro textarea(name, value, rows = 10, cols = 40) %} @@ -57,7 +57,7 @@ the ``forms`` local variable. The macros can then be called at will in the *current* template: -.. code-block:: twig +.. code-block:: html+twig

                  {{ forms.input('username') }}

                  {{ forms.input('password', null, 'password') }}

                  @@ -65,7 +65,7 @@ The macros can then be called at will in the *current* template: Alternatively you can import names from the template into the current namespace via the ``from`` tag: -.. code-block:: twig +.. code-block:: html+twig {% from 'forms.html' import input as input_field, textarea %} @@ -78,18 +78,18 @@ via the ``from`` tag: import the macros as they are automatically available under the special ``_self`` variable: - .. code-block:: twig + .. code-block:: html+twig

                  {{ _self.input('password', '', 'password') }}

                  {% macro input(name, value, type = "text", size = 20) %} - + {% endmacro %} Auto-import is only available as of Twig 2.11. For older versions, import macros using the special ``_self`` variable for the template name: - .. code-block:: twig + .. code-block:: html+twig {% import _self as forms %} @@ -100,10 +100,10 @@ via the ``from`` tag: Before Twig 2.11, when you want to use a macro in another macro from the same file, you need to import it locally: - .. code-block:: twig + .. code-block:: html+twig {% macro input(name, value, type, size) %} - + {% endmacro %} {% macro wrapped_input(name, value, type, size) %} @@ -128,7 +128,10 @@ The scoping rules are the same whether you imported macros via ``import`` or Imported macros are always **local** to the current template. It means that macros are available in all blocks and other macros defined in the current template, but they are not available in included templates or child templates; -you need to explicitely re-import macros in each template. +you need to explicitly re-import macros in each template. + +Imported macros are not available in the body of ``embed`` tags, you need +to explicitly re-import macros inside the tag. When calling ``import`` or ``from`` from a ``block`` tag, the imported macros are only defined in the current block and they override macros defined at the diff --git a/vendor/twig/twig/doc/tags/set.rst b/vendor/twig/twig/doc/tags/set.rst index f752fddb6..7a3a784f5 100644 --- a/vendor/twig/twig/doc/tags/set.rst +++ b/vendor/twig/twig/doc/tags/set.rst @@ -40,7 +40,7 @@ Several variables can be assigned in one block: The ``set`` tag can also be used to 'capture' chunks of text: -.. code-block:: twig +.. code-block:: html+twig {% set foo %}
    def
    g No item No item