diff --git a/app/code/Magento/AdminNotification/view/adminhtml/templates/system/messages/popup.phtml b/app/code/Magento/AdminNotification/view/adminhtml/templates/system/messages/popup.phtml index a97293547e132..d654504a41e5c 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/templates/system/messages/popup.phtml +++ b/app/code/Magento/AdminNotification/view/adminhtml/templates/system/messages/popup.phtml @@ -19,20 +19,12 @@ - + \ No newline at end of file diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/js/system/messages/popup.js b/app/code/Magento/AdminNotification/view/adminhtml/web/js/system/messages/popup.js new file mode 100644 index 0000000000000..f3f6a5fb1a123 --- /dev/null +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/js/system/messages/popup.js @@ -0,0 +1,24 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. +*/ + +define([ + 'jquery', + 'Magento_Ui/js/modal/modal' +], function ($) { + 'use strict'; + + return function (data, element) { + if (this.modal) { + this.modal.html($(element).html()); + } else { + this.modal = $(element).modal({ + modalClass: data.class, + type: 'popup', + buttons: [] + }); + } + this.modal.modal('openModal'); + }; +}); diff --git a/app/code/Magento/AsynchronousOperations/Api/BulkStatusInterface.php b/app/code/Magento/AsynchronousOperations/Api/BulkStatusInterface.php index 88db2d6d80141..76410794900e2 100644 --- a/app/code/Magento/AsynchronousOperations/Api/BulkStatusInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/BulkStatusInterface.php @@ -9,7 +9,8 @@ namespace Magento\AsynchronousOperations\Api; /** - * Interface BulkStatusInterface + * Interface BulkStatusInterface. + * * Bulk summary data with list of operations items short data. * * @api diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/DetailedBulkOperationsStatusInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/DetailedBulkOperationsStatusInterface.php index 3edc5167e0935..6e39177630857 100644 --- a/app/code/Magento/AsynchronousOperations/Api/Data/DetailedBulkOperationsStatusInterface.php +++ b/app/code/Magento/AsynchronousOperations/Api/Data/DetailedBulkOperationsStatusInterface.php @@ -23,14 +23,14 @@ interface DetailedBulkOperationsStatusInterface extends BulkSummaryInterface /** * Retrieve operations list. * - * @return \Magento\AsynchronousOperations\Api\Data\DetailedOperationStatusInterface[] + * @return \Magento\AsynchronousOperations\Api\Data\OperationInterface[] */ public function getOperationsList(); /** * Set operations list. * - * @param \Magento\AsynchronousOperations\Api\Data\DetailedOperationStatusInterface[] $operationStatusList + * @param \Magento\AsynchronousOperations\Api\Data\OperationInterface[] $operationStatusList * @return $this */ public function setOperationsList($operationStatusList); diff --git a/app/code/Magento/AsynchronousOperations/Api/Data/DetailedOperationStatusInterface.php b/app/code/Magento/AsynchronousOperations/Api/Data/DetailedOperationStatusInterface.php deleted file mode 100644 index 217d4ad9279b6..0000000000000 --- a/app/code/Magento/AsynchronousOperations/Api/Data/DetailedOperationStatusInterface.php +++ /dev/null @@ -1,30 +0,0 @@ -entityManager = $entityManager; @@ -65,7 +65,6 @@ public function changeOperationStatus( $operationEntity->setResultMessage($message); $operationEntity->setSerializedData($data); $operationEntity->setResultSerializedData($resultData); - $operationEntity->setResultSerializedData($resultData); $this->entityManager->save($operationEntity); } catch (\Exception $exception) { $this->logger->critical($exception->getMessage()); diff --git a/app/code/Magento/AsynchronousOperations/Model/OperationRepository.php b/app/code/Magento/AsynchronousOperations/Model/OperationRepository.php new file mode 100644 index 0000000000000..ec76ff6519757 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Model/OperationRepository.php @@ -0,0 +1,108 @@ +entityManager = $entityManager; + $this->collectionFactory = $collectionFactory; + $this->searchResultFactory = $searchResultFactory; + $this->joinProcessor = $joinProcessor; + $this->operationExtensionFactory = $operationExtension; + $this->collectionProcessor = $collectionProcessor; + $this->logger = $logger; + $this->collectionProcessor = $collectionProcessor; + } + + /** + * @inheritDoc + */ + public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria) + { + /** @var \Magento\AsynchronousOperations\Api\Data\OperationSearchResultsInterface $searchResult */ + $searchResult = $this->searchResultFactory->create(); + + /** @var \Magento\AsynchronousOperations\Model\ResourceModel\Operation\Collection $collection */ + $collection = $this->collectionFactory->create(); + $this->joinProcessor->process($collection, \Magento\AsynchronousOperations\Api\Data\OperationInterface::class); + $this->collectionProcessor->process($searchCriteria, $collection); + $searchResult->setSearchCriteria($searchCriteria); + $searchResult->setTotalCount($collection->getSize()); + $searchResult->setItems($collection->getItems()); + + return $searchResult; + } +} diff --git a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/OperationManagementTest.php b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/OperationManagementTest.php index 0a4e5f2f3ecc3..4c3e240da2a8a 100644 --- a/app/code/Magento/AsynchronousOperations/Test/Unit/Model/OperationManagementTest.php +++ b/app/code/Magento/AsynchronousOperations/Test/Unit/Model/OperationManagementTest.php @@ -40,11 +40,11 @@ protected function setUp() $this->entityManagerMock = $this->createMock(\Magento\Framework\EntityManager\EntityManager::class); $this->metadataPoolMock = $this->createMock(\Magento\Framework\EntityManager\MetadataPool::class); $this->operationFactoryMock = $this->createPartialMock( - \Magento\AsynchronousOperations\Api\Data\DetailedOperationStatusInterfaceFactory::class, + \Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory::class, ['create'] ); $this->operationMock = - $this->createMock(\Magento\AsynchronousOperations\Api\Data\DetailedOperationStatusInterface::class); + $this->createMock(\Magento\AsynchronousOperations\Api\Data\OperationInterface::class); $this->loggerMock = $this->createMock(\Psr\Log\LoggerInterface::class); $this->model = new \Magento\AsynchronousOperations\Model\OperationManagement( $this->entityManagerMock, diff --git a/app/code/Magento/AsynchronousOperations/etc/di.xml b/app/code/Magento/AsynchronousOperations/etc/di.xml index c8fee29cd6838..42b62ff8ea374 100644 --- a/app/code/Magento/AsynchronousOperations/etc/di.xml +++ b/app/code/Magento/AsynchronousOperations/etc/di.xml @@ -8,7 +8,6 @@ - @@ -17,10 +16,12 @@ + + - + magento_operation id diff --git a/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml b/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml new file mode 100644 index 0000000000000..6eeda62373f06 --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/etc/extension_attributes.xml @@ -0,0 +1,19 @@ + + + + + + + + + + start_time + + + + diff --git a/app/code/Magento/AsynchronousOperations/etc/webapi.xml b/app/code/Magento/AsynchronousOperations/etc/webapi.xml index 253dedd1c7a0c..4c10a5756c8d6 100644 --- a/app/code/Magento/AsynchronousOperations/etc/webapi.xml +++ b/app/code/Magento/AsynchronousOperations/etc/webapi.xml @@ -29,4 +29,11 @@ + + + + + + + diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteStorePost.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteStorePost.php index ac470238e588f..13b104c5ec4c0 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteStorePost.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteStorePost.php @@ -37,8 +37,6 @@ public function execute() try { $model->delete(); - $this->_eventManager->dispatch('store_delete', ['store' => $model]); - $this->messageManager->addSuccess(__('You deleted the store view.')); return $redirectResult->setPath('adminhtml/*/'); } catch (\Magento\Framework\Exception\LocalizedException $e) { diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/Save.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/Save.php index 1d6862a6ff845..8ca783f887ec4 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/Save.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/Save.php @@ -46,7 +46,6 @@ private function processWebsiteSave($postData) */ private function processStoreSave($postData) { - $eventName = 'store_edit'; /** @var \Magento\Store\Model\Store $storeModel */ $storeModel = $this->_objectManager->create(\Magento\Store\Model\Store::class); $postData['store']['name'] = $this->filterManager->removeTags($postData['store']['name']); @@ -56,7 +55,6 @@ private function processStoreSave($postData) $storeModel->setData($postData['store']); if ($postData['store']['store_id'] == '') { $storeModel->setId(null); - $eventName = 'store_add'; } $groupModel = $this->_objectManager->create( \Magento\Store\Model\Group::class @@ -70,8 +68,6 @@ private function processStoreSave($postData) ); } $storeModel->save(); - $this->_objectManager->get(\Magento\Store\Model\StoreManager::class)->reinitStores(); - $this->_eventManager->dispatch($eventName, ['store' => $storeModel]); $this->messageManager->addSuccess(__('You saved the store view.')); return $postData; @@ -102,7 +98,6 @@ private function processGroupSave($postData) ); } $groupModel->save(); - $this->_eventManager->dispatch('store_group_save', ['group' => $groupModel]); $this->messageManager->addSuccess(__('You saved the store.')); return $postData; diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json index aa2b9e12f7701..84c9a97698b71 100644 --- a/app/code/Magento/Bundle/composer.json +++ b/app/code/Magento/Bundle/composer.json @@ -25,7 +25,8 @@ }, "suggest": { "magento/module-webapi": "*", - "magento/module-bundle-sample-data": "*" + "magento/module-bundle-sample-data": "*", + "magento/module-sales-rule": "*" }, "type": "magento2-module", "license": [ diff --git a/app/code/Magento/Bundle/etc/di.xml b/app/code/Magento/Bundle/etc/di.xml index b7fba3937ded4..733b089dccd4b 100644 --- a/app/code/Magento/Bundle/etc/di.xml +++ b/app/code/Magento/Bundle/etc/di.xml @@ -207,4 +207,11 @@ + + + + false + + + diff --git a/app/code/Magento/Captcha/Test/Unit/Observer/CheckRegisterCheckoutObserverTest.php b/app/code/Magento/Captcha/Test/Unit/Observer/CheckRegisterCheckoutObserverTest.php new file mode 100644 index 0000000000000..89012ef653838 --- /dev/null +++ b/app/code/Magento/Captcha/Test/Unit/Observer/CheckRegisterCheckoutObserverTest.php @@ -0,0 +1,211 @@ +createMock(Onepage::class); + $captchaHelperMock = $this->createMock(CaptchaDataHelper::class); + $this->objectManager = new ObjectManager($this); + $this->actionFlagMock = $this->createMock(ActionFlag::class); + $this->captchaStringResolverMock = $this->createMock(CaptchaStringResolver::class); + $this->captchaModelMock = $this->createMock(CaptchaModel::class); + $this->quoteModelMock = $this->createMock(Quote::class); + $this->controllerMock = $this->createMock(Action::class); + $this->requestMock = $this->createMock(Http::class); + $this->responseMock = $this->createMock(HttpResponse::class); + $this->observer = new Observer(['controller_action' => $this->controllerMock]); + $this->jsonHelperMock = $this->createMock(JsonHelper::class); + + $this->checkRegisterCheckoutObserver = $this->objectManager->getObject( + CheckRegisterCheckoutObserver::class, + [ + 'helper' => $captchaHelperMock, + 'actionFlag' => $this->actionFlagMock, + 'captchaStringResolver' => $this->captchaStringResolverMock, + 'typeOnepage' => $onepageModelTypeMock, + 'jsonHelper' => $this->jsonHelperMock + ] + ); + + $captchaHelperMock->expects($this->once()) + ->method('getCaptcha') + ->with(self::FORM_ID) + ->willReturn($this->captchaModelMock); + $onepageModelTypeMock->expects($this->once()) + ->method('getQuote') + ->willReturn($this->quoteModelMock); + } + + public function testCheckRegisterCheckoutForGuest() + { + $this->quoteModelMock->expects($this->once()) + ->method('getCheckoutMethod') + ->willReturn(Onepage::METHOD_GUEST); + $this->captchaModelMock->expects($this->never()) + ->method('isRequired'); + + $this->checkRegisterCheckoutObserver->execute($this->observer); + } + + public function testCheckRegisterCheckoutWithNoCaptchaRequired() + { + $this->quoteModelMock->expects($this->once()) + ->method('getCheckoutMethod') + ->willReturn(Onepage::METHOD_REGISTER); + $this->captchaModelMock->expects($this->once()) + ->method('isRequired') + ->willReturn(false); + $this->captchaModelMock->expects($this->never()) + ->method('isCorrect'); + + $this->checkRegisterCheckoutObserver->execute($this->observer); + } + + public function testCheckRegisterCheckoutWithIncorrectCaptcha() + { + $captchaValue = 'some_word'; + $encodedJsonValue = '{}'; + + $this->quoteModelMock->expects($this->once()) + ->method('getCheckoutMethod') + ->willReturn(Onepage::METHOD_REGISTER); + $this->captchaModelMock->expects($this->once()) + ->method('isRequired') + ->willReturn(true); + $this->controllerMock->expects($this->once()) + ->method('getRequest') + ->willReturn($this->requestMock); + $this->controllerMock->expects($this->once()) + ->method('getResponse') + ->willReturn($this->responseMock); + $this->controllerMock->expects($this->once()) + ->method('getResponse') + ->willReturn($this->responseMock); + $this->captchaStringResolverMock->expects($this->once()) + ->method('resolve') + ->with($this->requestMock, self::FORM_ID) + ->willReturn($captchaValue); + $this->captchaModelMock->expects($this->once()) + ->method('isCorrect') + ->with($captchaValue) + ->willReturn(false); + $this->actionFlagMock->expects($this->once()) + ->method('set') + ->with('', Action::FLAG_NO_DISPATCH, true); + $this->jsonHelperMock->expects($this->once()) + ->method('jsonEncode') + ->willReturn($encodedJsonValue); + $this->responseMock->expects($this->once()) + ->method('representJson') + ->with($encodedJsonValue); + + $this->checkRegisterCheckoutObserver->execute($this->observer); + } + + public function testCheckRegisterCheckoutWithCorrectCaptcha() + { + $this->quoteModelMock->expects($this->once()) + ->method('getCheckoutMethod') + ->willReturn(Onepage::METHOD_REGISTER); + $this->captchaModelMock->expects($this->once()) + ->method('isRequired') + ->willReturn(true); + $this->controllerMock->expects($this->once()) + ->method('getRequest') + ->willReturn($this->requestMock); + $this->captchaStringResolverMock->expects($this->once()) + ->method('resolve') + ->with($this->requestMock, self::FORM_ID) + ->willReturn('some_word'); + $this->captchaModelMock->expects($this->once()) + ->method('isCorrect') + ->with('some_word') + ->willReturn(true); + $this->actionFlagMock->expects($this->never()) + ->method('set'); + + $this->checkRegisterCheckoutObserver->execute($this->observer); + } +} diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index c53691ecada24..39dec984a19cc 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -196,7 +196,7 @@ public function setCollection($collection) $this->_collection->addAttributeToSort( $this->getCurrentOrder(), $this->getCurrentDirection() - )->addAttributeToSort('entity_id', $this->getCurrentDirection()); + ); } else { $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection()); } diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category.php index 13c4353e65204..1e0cb9f197a51 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Category.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category.php @@ -3,8 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Controller\Adminhtml; +use Magento\Store\Model\Store; + /** * Catalog category controller */ @@ -44,7 +48,7 @@ public function __construct( protected function _initCategory($getRootInstead = false) { $categoryId = $this->resolveCategoryId(); - $storeId = (int)$this->getRequest()->getParam('store'); + $storeId = $this->resolveStoreId(); $category = $this->_objectManager->create(\Magento\Catalog\Model\Category::class); $category->setStoreId($storeId); @@ -70,7 +74,7 @@ protected function _initCategory($getRootInstead = false) $this->_objectManager->get(\Magento\Framework\Registry::class)->register('category', $category); $this->_objectManager->get(\Magento\Framework\Registry::class)->register('current_category', $category); $this->_objectManager->get(\Magento\Cms\Model\Wysiwyg\Config::class) - ->setStoreId($this->getRequest()->getParam('store')); + ->setStoreId($storeId); return $category; } @@ -79,13 +83,28 @@ protected function _initCategory($getRootInstead = false) * * @return int */ - private function resolveCategoryId() + private function resolveCategoryId() : int { $categoryId = (int)$this->getRequest()->getParam('id', false); return $categoryId ?: (int)$this->getRequest()->getParam('entity_id', false); } + /** + * Resolve store id + * + * Tries to take store id from store HTTP parameter + * @see Store + * + * @return int + */ + private function resolveStoreId() : int + { + $storeId = (int)$this->getRequest()->getParam('store', false); + + return $storeId ?: (int)$this->getRequest()->getParam('store_id', Store::DEFAULT_STORE_ID); + } + /** * Build response for ajax request * diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php index e054a9d49b437..817de6828e48d 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php @@ -69,6 +69,7 @@ class Save extends Attribute * @var LayoutFactory */ private $layoutFactory; + /** * @var Presentation */ @@ -124,6 +125,7 @@ public function execute() { $data = $this->getRequest()->getPostValue(); if ($data) { + $this->preprocessOptionsData($data); $setId = $this->getRequest()->getParam('set'); $attributeSet = null; @@ -313,6 +315,28 @@ public function execute() return $this->returnResult('catalog/*/', [], ['error' => true]); } + /** + * Extract options data from serialized options field and append to data array. + * + * This logic is required to overcome max_input_vars php limit + * that may vary and/or be inaccessible to change on different instances. + * + * @param array $data + * @return void + */ + private function preprocessOptionsData(&$data) + { + if (isset($data['serialized_options'])) { + $serializedOptions = json_decode($data['serialized_options'], JSON_OBJECT_AS_ARRAY); + foreach ($serializedOptions as $serializedOption) { + $option = []; + parse_str($serializedOption, $option); + $data = array_replace_recursive($data, $option); + } + } + unset($data['serialized_options']); + } + /** * @param string $path * @param array $params diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php index 1481687205ddb..84837262a8154 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php @@ -216,6 +216,9 @@ private function handleImageRemoveError($postData, $productId) /** * Do copying data to stores * + * If the 'copy_from' field is not specified in the input data, + * the store fallback mechanism will automatically take the admin store's default value. + * * @param array $data * @param int $productId * @return void @@ -227,15 +230,17 @@ protected function copyToStores($data, $productId) if (isset($data['product']['website_ids'][$websiteId]) && (bool)$data['product']['website_ids'][$websiteId]) { foreach ($group as $store) { - $copyFrom = (isset($store['copy_from'])) ? $store['copy_from'] : 0; - $copyTo = (isset($store['copy_to'])) ? $store['copy_to'] : 0; - if ($copyTo) { - $this->_objectManager->create(\Magento\Catalog\Model\Product::class) - ->setStoreId($copyFrom) - ->load($productId) - ->setStoreId($copyTo) - ->setCopyFromView(true) - ->save(); + if (isset($store['copy_from'])) { + $copyFrom = $store['copy_from']; + $copyTo = (isset($store['copy_to'])) ? $store['copy_to'] : 0; + if ($copyTo) { + $this->_objectManager->create(\Magento\Catalog\Model\Product::class) + ->setStoreId($copyFrom) + ->load($productId) + ->setStoreId($copyTo) + ->setCopyFromView(true) + ->save(); + } } } } diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index 03ddab3d44547..4c0122694285d 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -334,9 +334,7 @@ protected function initializeProductData(array $productData, $createNew) unset($productData['media_gallery']); if ($createNew) { $product = $this->productFactory->create(); - if ($this->storeManager->hasSingleStore()) { - $product->setWebsiteIds([$this->storeManager->getStore(true)->getWebsiteId()]); - } + $this->assignProductToWebsites($product); } else { $this->removeProductFromLocalCache($productData['sku']); $product = $this->get($productData['sku']); @@ -345,31 +343,20 @@ protected function initializeProductData(array $productData, $createNew) foreach ($productData as $key => $value) { $product->setData($key, $value); } - $this->assignProductToWebsites($product, $createNew); return $product; } /** * @param \Magento\Catalog\Model\Product $product - * @param bool $createNew * @return void */ - private function assignProductToWebsites(\Magento\Catalog\Model\Product $product, $createNew) + private function assignProductToWebsites(\Magento\Catalog\Model\Product $product) { - $websiteIds = $product->getWebsiteIds(); - - if (!$this->storeManager->hasSingleStore()) { - $websiteIds = array_unique( - array_merge( - $websiteIds, - [$this->storeManager->getStore()->getWebsiteId()] - ) - ); - } - - if ($createNew && $this->storeManager->getStore(true)->getCode() == \Magento\Store\Model\Store::ADMIN_CODE) { + if ($this->storeManager->getStore(true)->getCode() == \Magento\Store\Model\Store::ADMIN_CODE) { $websiteIds = array_keys($this->storeManager->getWebsites()); + } else { + $websiteIds = [$this->storeManager->getStore()->getWebsiteId()]; } $product->setWebsiteIds($websiteIds); diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Attribute.php b/app/code/Magento/Catalog/Model/ResourceModel/Attribute.php index bdb3cdab617ac..8457e5d0eaa5c 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Attribute.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Attribute.php @@ -141,19 +141,17 @@ public function deleteEntity(\Magento\Framework\Model\AbstractModel $object) ->getMetadata(ProductInterface::class) ->getLinkField(); - $select = $this->getConnection()->select()->from( - $attribute->getEntity()->getEntityTable(), - $linkField - )->where( - 'attribute_set_id = ?', - $result['attribute_set_id'] - ); + $backendLinkField = $attribute->getBackend()->getEntityIdField(); - $clearCondition = [ - 'attribute_id =?' => $attribute->getId(), - $linkField . ' IN (?)' => $select, - ]; - $this->getConnection()->delete($backendTable, $clearCondition); + $select = $this->getConnection()->select() + ->from(['b' => $backendTable]) + ->join( + ['e' => $attribute->getEntity()->getEntityTable()], + "b.$backendLinkField = e.$linkField" + )->where('b.attribute_id = ?', $attribute->getId()) + ->where('e.attribute_set_id = ?', $result['attribute_set_id']); + + $this->getConnection()->query($select->deleteFromSelect('b')); } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index bf5c3d8276295..a1cf6662d78f0 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -553,7 +553,6 @@ public function testGetBySkuFromCacheInitializedInGetById() public function testSaveExisting() { - $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']); $this->resourceModelMock->expects($this->any())->method('getIdBySku')->will($this->returnValue(100)); $this->productFactoryMock->expects($this->any()) ->method('create') @@ -566,7 +565,6 @@ public function testSaveExisting() ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->productMock->expects($this->atLeastOnce())->method('getSku')->willReturn($this->productData['sku']); $this->assertEquals($this->productMock, $this->model->save($this->productMock)); @@ -588,7 +586,6 @@ public function testSaveNew() ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->method('getWebsiteIds')->willReturn([]); $this->productMock->method('getSku')->willReturn('simple'); $this->assertEquals($this->productMock, $this->model->save($this->productMock)); @@ -615,7 +612,6 @@ public function testSaveUnableToSaveException() ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->method('getWebsiteIds')->willReturn([]); $this->productMock->method('getSku')->willReturn('simple'); $this->model->save($this->productMock); @@ -642,7 +638,6 @@ public function testSaveException() ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->productMock->method('getSku')->willReturn('simple'); $this->model->save($this->productMock); @@ -667,7 +662,6 @@ public function testSaveInvalidProductException() ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->productMock->method('getSku')->willReturn('simple'); $this->model->save($this->productMock); @@ -697,9 +691,6 @@ public function testSaveThrowsTemporaryStateExceptionIfDatabaseConnectionErrorOc ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->expects($this->once()) - ->method('getWebsiteIds') - ->willReturn([]); $this->productMock->method('getSku')->willReturn('simple'); $this->model->save($this->productMock); @@ -847,7 +838,6 @@ public function testSaveExistingWithOptions(array $newOptions, array $existingOp ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->initializedProductMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->initializedProductMock->expects($this->atLeastOnce()) ->method('getSku')->willReturn($this->productData['sku']); $this->productMock->expects($this->atLeastOnce())->method('getSku')->willReturn($this->productData['sku']); @@ -1083,7 +1073,6 @@ public function testSaveWithLinks(array $newLinks, array $existingLinks, array $ $outputLinks[] = $outputLink; } } - $this->initializedProductMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); if (!empty($outputLinks)) { $this->initializedProductMock->expects($this->once()) @@ -1264,7 +1253,6 @@ public function testSaveExistingWithNewMediaGalleryEntries() 'media_type' => 'media_type', ] ); - $this->initializedProductMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->initializedProductMock->expects($this->atLeastOnce()) ->method('getSku')->willReturn($this->productData['sku']); $this->productMock->expects($this->atLeastOnce())->method('getSku')->willReturn($this->productData['sku']); @@ -1305,7 +1293,6 @@ public function testSaveWithDifferentWebsites() 2 => ['second'], 3 => ['third'] ]); - $this->productMock->expects($this->once())->method('getWebsiteIds')->willReturn([1,2,3]); $this->productMock->expects($this->once())->method('setWebsiteIds')->willReturn([2,3]); $this->productMock->method('getSku')->willReturn('simple'); @@ -1377,7 +1364,6 @@ public function testSaveExistingWithMediaGalleryEntries() $this->mediaGalleryProcessor->expects($this->once()) ->method('setMediaAttribute') ->with($this->initializedProductMock, ['image', 'small_image'], 'filename1'); - $this->initializedProductMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->initializedProductMock->expects($this->atLeastOnce()) ->method('getSku')->willReturn($this->productData['sku']); $this->productMock->expects($this->atLeastOnce())->method('getSku')->willReturn($this->productData['sku']); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/AttributeTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/AttributeTest.php new file mode 100644 index 0000000000000..0501d995aaf53 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/AttributeTest.php @@ -0,0 +1,230 @@ +selectMock = $this->getMockBuilder(Select::class) + ->disableOriginalConstructor() + ->setMethods(['from', 'where', 'join', 'deleteFromSelect']) + ->getMock(); + + $this->connectionMock = $this->getMockBuilder(Adapter::class)->getMockForAbstractClass(); + $this->connectionMock->expects($this->once())->method('select')->willReturn($this->selectMock); + $this->connectionMock->expects($this->once())->method('query')->willReturn($this->selectMock); + $this->connectionMock->expects($this->once())->method('delete')->willReturn($this->selectMock); + $this->selectMock->expects($this->once())->method('from')->willReturnSelf(); + $this->selectMock->expects($this->once())->method('join')->willReturnSelf(); + $this->selectMock->expects($this->any())->method('where')->willReturnSelf(); + $this->selectMock->expects($this->any())->method('deleteFromSelect')->willReturnSelf(); + + $this->resourceMock = $this->getMockBuilder(ResourceConnection::class) + ->disableOriginalConstructor() + ->setMethods(['delete', 'getConnection']) + ->getMock(); + + $this->contextMock = $this->getMockBuilder(Context::class)->disableOriginalConstructor()->getMock(); + $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)->getMock(); + $this->eavEntityTypeMock = $this->getMockBuilder(Type::class) + ->disableOriginalConstructor() + ->getMock(); + $this->eavConfigMock = $this->getMockBuilder(\Magento\Eav\Model\Config::class) + ->disableOriginalConstructor() + ->setMethods(['getAttribute']) + ->getMock(); + $this->lockValidatorMock = $this->getMockBuilder(LockValidatorInterface::class) + ->disableOriginalConstructor() + ->setMethods(['validate']) + ->getMock(); + $this->entityMetaDataInterfaceMock = $this->getMockBuilder(EntityMetadataInterface::class) + ->disableOriginalConstructor() + ->getMock(); + } + + /** + * Sets object non-public property. + * + * @param mixed $object + * @param string $propertyName + * @param mixed $value + * + * @return void + */ + private function setObjectProperty($object, string $propertyName, $value) : void + { + $reflectionClass = new \ReflectionClass($object); + $reflectionProperty = $reflectionClass->getProperty($propertyName); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($object, $value); + } + + /** + * @return void + */ + public function testDeleteEntity() : void + { + $entityAttributeId = 196; + $entityTypeId = 4; + $result = [ + 'entity_attribute_id' => 196, + 'entity_type_id' => 4, + 'attribute_set_id'=> 4, + 'attribute_group_id' => 7, + 'attribute_id' => 177, + 'sort_order' => 3, + ]; + + $backendTableName = 'weee_tax'; + $backendFieldName = 'value_id'; + + $attributeModel = $this->getMockBuilder(Attribute::class) + ->setMethods(['getEntityAttribute', 'getMetadataPool', 'getConnection', 'getTable']) + ->setConstructorArgs([ + $this->contextMock, + $this->storeManagerMock, + $this->eavEntityTypeMock, + $this->eavConfigMock, + $this->lockValidatorMock, + null, + ])->getMock(); + $attributeModel->expects($this->any()) + ->method('getEntityAttribute') + ->with($entityAttributeId) + ->willReturn($result); + $metadataPoolMock = $this->getMockBuilder(MetadataPool::class) + ->disableOriginalConstructor() + ->setMethods(['getMetadata']) + ->getMock(); + + $this->setObjectProperty($attributeModel, 'metadataPool', $metadataPoolMock); + + $eavAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class) + ->disableOriginalConstructor() + ->getMock(); + + $eavAttributeMock->expects($this->any())->method('getId')->willReturn($result['attribute_id']); + + $this->eavConfigMock->expects($this->any()) + ->method('getAttribute') + ->with($entityTypeId, $result['attribute_id']) + ->willReturn($eavAttributeMock); + + $abstractModelMock = $this->getMockBuilder(AbstractModel::class) + ->disableOriginalConstructor() + ->setMethods(['getEntityAttributeId','getEntityTypeId']) + ->getMockForAbstractClass(); + $abstractModelMock->expects($this->any())->method('getEntityAttributeId')->willReturn($entityAttributeId); + $abstractModelMock->expects($this->any())->method('getEntityTypeId')->willReturn($entityTypeId); + + $this->lockValidatorMock->expects($this->any()) + ->method('validate') + ->with($eavAttributeMock, $result['attribute_set_id']) + ->willReturn(true); + + $backendModelMock = $this->getMockBuilder(AbstractBackend::class) + ->disableOriginalConstructor() + ->setMethods(['getBackend', 'getTable', 'getEntityIdField']) + ->getMock(); + + $abstractAttributeMock = $this->getMockBuilder(AbstractAttribute::class) + ->disableOriginalConstructor() + ->setMethods(['getEntity']) + ->getMockForAbstractClass(); + + $eavAttributeMock->expects($this->any())->method('getBackend')->willReturn($backendModelMock); + $eavAttributeMock->expects($this->any())->method('getEntity')->willReturn($abstractAttributeMock); + + $backendModelMock->expects($this->any())->method('getTable')->willReturn($backendTableName); + $backendModelMock->expects($this->once())->method('getEntityIdField')->willReturn($backendFieldName); + + $metadataPoolMock->expects($this->any()) + ->method('getMetadata') + ->with(ProductInterface::class) + ->willReturn($this->entityMetaDataInterfaceMock); + + $this->entityMetaDataInterfaceMock->expects($this->any()) + ->method('getLinkField') + ->willReturn('row_id'); + + $attributeModel->expects($this->any())->method('getConnection')->willReturn($this->connectionMock); + $attributeModel->expects($this->any()) + ->method('getTable') + ->with('eav_entity_attribute') + ->willReturn('eav_entity_attribute'); + + $attributeModel->deleteEntity($abstractModelMock); + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php new file mode 100644 index 0000000000000..604136bb3ad4b --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php @@ -0,0 +1,238 @@ +objectManager = new ObjectManager($this); + + $this->contextMock = $this->getMockBuilder(ContextInterface::class) + ->getMockForAbstractClass(); + $this->authorizationMock = $this->getMockBuilder(AuthorizationInterface::class) + ->getMockForAbstractClass(); + + $this->massAction = $this->objectManager->getObject( + MassAction::class, + [ + 'authorization' => $this->authorizationMock, + 'context' => $this->contextMock, + 'data' => [] + ] + ); + } + + public function testGetComponentName() + { + $this->assertTrue($this->massAction->getComponentName() === MassAction::NAME); + } + + /** + * @param string $componentName + * @param array $componentData + * @param bool $isAllowed + * @param bool $expectActionConfig + * @return void + * @dataProvider getPrepareDataProvider + */ + public function testPrepare($componentName, $componentData, $isAllowed = true, $expectActionConfig = true) + { + $processor = $this->getMockBuilder(\Magento\Framework\View\Element\UiComponent\Processor::class) + ->disableOriginalConstructor() + ->getMock(); + $this->contextMock->expects($this->atLeastOnce())->method('getProcessor')->willReturn($processor); + /** @var \Magento\Ui\Component\MassAction $action */ + $action = $this->objectManager->getObject( + \Magento\Ui\Component\MassAction::class, + [ + 'context' => $this->contextMock, + 'data' => [ + 'name' => $componentName, + 'config' => $componentData, + ] + ] + ); + $this->authorizationMock->method('isAllowed') + ->willReturn($isAllowed); + $this->massAction->addComponent('action', $action); + $this->massAction->prepare(); + $expected = $expectActionConfig ? ['actions' => [$action->getConfiguration()]] : []; + $this->assertEquals($expected, $this->massAction->getConfiguration()); + } + + /** + * @return array + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function getPrepareDataProvider() : array + { + return [ + [ + 'test_component1', + [ + 'type' => 'first_action', + 'label' => 'First Action', + 'url' => '/module/controller/firstAction' + ], + ], + [ + 'test_component2', + [ + 'type' => 'second_action', + 'label' => 'Second Action', + 'actions' => [ + [ + 'type' => 'second_sub_action1', + 'label' => 'Second Sub Action 1', + 'url' => '/module/controller/secondSubAction1' + ], + [ + 'type' => 'second_sub_action2', + 'label' => 'Second Sub Action 2', + 'url' => '/module/controller/secondSubAction2' + ], + ] + ], + ], + [ + 'status_component', + [ + 'type' => 'status', + 'label' => 'Status', + 'actions' => [ + [ + 'type' => 'enable', + 'label' => 'Second Sub Action 1', + 'url' => '/module/controller/enable' + ], + [ + 'type' => 'disable', + 'label' => 'Second Sub Action 2', + 'url' => '/module/controller/disable' + ], + ] + ], + ], + [ + 'status_component_not_allowed', + [ + 'type' => 'status', + 'label' => 'Status', + 'actions' => [ + [ + 'type' => 'enable', + 'label' => 'Second Sub Action 1', + 'url' => '/module/controller/enable' + ], + [ + 'type' => 'disable', + 'label' => 'Second Sub Action 2', + 'url' => '/module/controller/disable' + ], + ] + ], + false, + false + ], + [ + 'delete_component', + [ + 'type' => 'delete', + 'label' => 'First Action', + 'url' => '/module/controller/delete' + ], + ], + [ + 'delete_component_not_allowed', + [ + 'type' => 'delete', + 'label' => 'First Action', + 'url' => '/module/controller/delete' + ], + false, + false + ], + [ + 'attributes_component', + [ + 'type' => 'delete', + 'label' => 'First Action', + 'url' => '/module/controller/attributes' + ], + ], + [ + 'attributes_component_not_allowed', + [ + 'type' => 'delete', + 'label' => 'First Action', + 'url' => '/module/controller/attributes' + ], + false, + false + ], + ]; + } + + /** + * @param bool $expected + * @param string $actionType + * @param int $callNum + * @param string $resource + * @param bool $isAllowed + * @dataProvider isActionAllowedDataProvider + */ + public function testIsActionAllowed($expected, $actionType, $callNum, $resource = '', $isAllowed = true) + { + $this->authorizationMock->expects($this->exactly($callNum)) + ->method('isAllowed') + ->with($resource) + ->willReturn($isAllowed); + + $this->assertEquals($expected, $this->massAction->isActionAllowed($actionType)); + } + + public function isActionAllowedDataProvider() + { + return [ + 'other' => [true, 'other', 0,], + 'delete-allowed' => [true, 'delete', 1, 'Magento_Catalog::products'], + 'delete-not-allowed' => [false, 'delete', 1, 'Magento_Catalog::products', false], + 'status-allowed' => [true, 'status', 1, 'Magento_Catalog::products'], + 'status-not-allowed' => [false, 'status', 1, 'Magento_Catalog::products', false], + 'attributes-allowed' => [true, 'attributes', 1, 'Magento_Catalog::update_attributes'], + 'attributes-not-allowed' => [false, 'attributes', 1, 'Magento_Catalog::update_attributes', false], + + ]; + } +} diff --git a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php new file mode 100644 index 0000000000000..894e2b701b5ac --- /dev/null +++ b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php @@ -0,0 +1,98 @@ +authorization = $authorization; + parent::__construct($context, $components, $data); + } + + /** + * {@inheritdoc} + */ + public function prepare() : void + { + $config = $this->getConfiguration(); + + foreach ($this->getChildComponents() as $actionComponent) { + $actionType = $actionComponent->getConfiguration()['type']; + if ($this->isActionAllowed($actionType)) { + $config['actions'][] = $actionComponent->getConfiguration(); + } + } + $origConfig = $this->getConfiguration(); + if ($origConfig !== $config) { + $config = array_replace_recursive($config, $origConfig); + } + + $this->setData('config', $config); + $this->components = []; + + parent::prepare(); + } + + /** + * {@inheritdoc} + */ + public function getComponentName() : string + { + return static::NAME; + } + + /** + * Check if the given type of action is allowed + * + * @param string $actionType + * @return bool + */ + public function isActionAllowed($actionType) : bool + { + $isAllowed = true; + switch ($actionType) { + case 'delete': + $isAllowed = $this->authorization->isAllowed('Magento_Catalog::products'); + break; + case 'status': + $isAllowed = $this->authorization->isAllowed('Magento_Catalog::products'); + break; + case 'attributes': + $isAllowed = $this->authorization->isAllowed('Magento_Catalog::update_attributes'); + break; + default: + break; + } + return $isAllowed; + } +} diff --git a/app/code/Magento/Catalog/etc/adminhtml/menu.xml b/app/code/Magento/Catalog/etc/adminhtml/menu.xml index aa910e6d5ade4..cfcce3a26cbec 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/menu.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/menu.xml @@ -12,7 +12,6 @@ - diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index 6efd2d1c1eafe..60789c016ff0f 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -1809,7 +1809,7 @@ - diff --git a/app/code/Magento/Catalog/etc/db_schema_whitelist.json b/app/code/Magento/Catalog/etc/db_schema_whitelist.json index b38817331bee5..1c2c660ca9b00 100644 --- a/app/code/Magento/Catalog/etc/db_schema_whitelist.json +++ b/app/code/Magento/Catalog/etc/db_schema_whitelist.json @@ -1096,7 +1096,8 @@ "index": { "CAT_CTGR_PRD_IDX_REPLICA_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY": true, "IDX_87EB2E3059853CF89A75B4C55074810B": true, - "CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY": true + "CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY": true, + "CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION": true }, "constraint": { "PRIMARY": true @@ -1114,8 +1115,9 @@ "constraint": { "PRIMARY": true, "CAT_PRD_FRONTEND_ACTION_CSTR_ID_CSTR_ENTT_ENTT_ID": true, + "CAT_PRD_FRONTEND_ACTION_PRD_ID_CAT_PRD_ENTT_ENTT_ID": true, "CATALOG_PRODUCT_FRONTEND_ACTION_VISITOR_ID_PRODUCT_ID_TYPE_ID": true, "CATALOG_PRODUCT_FRONTEND_ACTION_CUSTOMER_ID_PRODUCT_ID_TYPE_ID": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/Catalog/etc/webapi_async.xml b/app/code/Magento/Catalog/etc/webapi_async.xml new file mode 100644 index 0000000000000..50baad7845e95 --- /dev/null +++ b/app/code/Magento/Catalog/etc/webapi_async.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/code/Magento/Catalog/view/adminhtml/ui_component/product_listing.xml b/app/code/Magento/Catalog/view/adminhtml/ui_component/product_listing.xml index 09332d66633f1..65090fa3ac461 100644 --- a/app/code/Magento/Catalog/view/adminhtml/ui_component/product_listing.xml +++ b/app/code/Magento/Catalog/view/adminhtml/ui_component/product_listing.xml @@ -48,7 +48,9 @@ - + diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 787516a9abf29..6ea005915763c 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -13,12 +13,16 @@ define([ 'jquery/ui', 'prototype', 'form', - 'validation' + 'validation', + 'mage/translate' ], function (jQuery, mageTemplate, rg) { 'use strict'; return function (config) { - var attributeOption = { + var optionPanel = jQuery('#manage-options-panel'), + optionsValues = [], + editForm = jQuery('#edit_form'), + attributeOption = { table: $('attribute-options-table'), itemCount: 0, totalItems: 0, @@ -150,7 +154,7 @@ define([ attributeOption.remove(event); }); - jQuery('#manage-options-panel').on('render', function () { + optionPanel.on('render', function () { attributeOption.ignoreValidate(); if (attributeOption.rendered) { @@ -176,7 +180,31 @@ define([ }); }); } + editForm.on('submit', function () { + optionPanel.find('input') + .each(function () { + if (this.disabled) { + return; + } + if (this.type === 'checkbox' || this.type === 'radio') { + if (this.checked) { + optionsValues.push(this.name + '=' + jQuery(this).val()); + } + } else { + optionsValues.push(this.name + '=' + jQuery(this).val()); + } + }); + jQuery('') + .attr({ + type: 'hidden', + name: 'serialized_options' + }) + .val(JSON.stringify(optionsValues)) + .prependTo(editForm); + optionPanel.find('table') + .replaceWith(jQuery('
').text(jQuery.mage.__('Sending attribute values as package.'))); + }); window.attributeOption = attributeOption; window.optionDefaultInputType = attributeOption.getOptionInputType(); diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/breadcrumbs.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/breadcrumbs.phtml index 528b2b5c59f23..063f8857329e5 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/breadcrumbs.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/breadcrumbs.phtml @@ -11,7 +11,7 @@ $viewModel = $block->getData('viewModel'); "breadcrumbs": { "categoryUrlSuffix": "escapeHtml($viewModel->getCategoryUrlSuffix()); ?>", "useCategoryPathInUrl": isCategoryUsedInProductUrl(); ?>, - "product": "escapeHtml($block->escapeJsQuote($viewModel->getProductName(), '"')); ?>" + "product": "escapeHtml($block->escapeJs($viewModel->getProductName())); ?>" } }'>
diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php similarity index 89% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Category.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php index a17de7374534b..378e7cb4c3673 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php @@ -20,15 +20,10 @@ use Magento\Framework\Reflection\DataObjectProcessor; /** - * Category field resolver, used for GraphQL request processing. + * Resolver for category objects the product is assigned to. */ -class Category implements ResolverInterface +class Categories implements ResolverInterface { - /** - * Product category ids - */ - const PRODUCT_CATEGORY_IDS_KEY = 'category_ids'; - /** * @var Collection */ @@ -89,10 +84,13 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) : Value { - $this->categoryIds = array_merge($this->categoryIds, $value[self::PRODUCT_CATEGORY_IDS_KEY]); + /** @var \Magento\Catalog\Model\Product $product */ + $product = $value['model']; + $categoryIds = $product->getCategoryIds(); + $this->categoryIds = array_merge($this->categoryIds, $categoryIds); $that = $this; - return $this->valueFactory->create(function () use ($that, $value, $info) { + return $this->valueFactory->create(function () use ($that, $categoryIds, $info) { $categories = []; if (empty($that->categoryIds)) { return []; @@ -104,7 +102,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value } /** @var CategoryInterface | \Magento\Catalog\Model\Category $item */ foreach ($this->collection as $item) { - if (in_array($item->getId(), $value[$that::PRODUCT_CATEGORY_IDS_KEY])) { + if (in_array($item->getId(), $categoryIds)) { $categories[$item->getId()] = $this->dataObjectProcessor->buildOutputDataArray( $item, CategoryInterface::class diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php index 5927e747c2238..406b4173e68e1 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php @@ -63,7 +63,7 @@ public function resolve( array $args = null ): Value { $args['filter'] = [ - 'category_ids' => [ + 'category_id' => [ 'eq' => $value['id'] ] ]; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php index f2020cbeca88e..2c73d7a079170 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product.php @@ -78,14 +78,14 @@ public function getList( $this->collectionProcessor->process($collection, $searchCriteria, $attributes); if (!$isChildSearch) { - $visibilityIds - = $isSearch ? $this->visibility->getVisibleInSearchIds() : $this->visibility->getVisibleInCatalogIds(); + $visibilityIds = $isSearch + ? $this->visibility->getVisibleInSearchIds() + : $this->visibility->getVisibleInCatalogIds(); $collection->setVisibility($visibilityIds); } $collection->load(); // Methods that perform extra fetches post-load - $collection->addCategoryIds(); $collection->addMediaGalleryData(); $collection->addOptionsToResult(); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ProductEntityAttributesForAst.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ProductEntityAttributesForAst.php index 96bef3ffc09c4..a547f63b217fe 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ProductEntityAttributesForAst.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/FilterArgument/ProductEntityAttributesForAst.php @@ -25,7 +25,7 @@ class ProductEntityAttributesForAst implements FieldEntityAttributesInterface /** * @var array */ - private $additionalAttributes; + private $additionalAttributes = ['min_price', 'max_price', 'category_id']; /** * @param ConfigInterface $config @@ -33,10 +33,10 @@ class ProductEntityAttributesForAst implements FieldEntityAttributesInterface */ public function __construct( ConfigInterface $config, - array $additionalAttributes = ['min_price', 'max_price', 'category_ids'] + array $additionalAttributes = [] ) { $this->config = $config; - $this->additionalAttributes = $additionalAttributes; + $this->additionalAttributes = array_merge($this->additionalAttributes, $additionalAttributes); } /** diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php new file mode 100644 index 0000000000000..e3b3588166163 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php @@ -0,0 +1,71 @@ +categoryFactory = $categoryFactory; + $this->categoryResourceModel = $categoryResourceModel; + } + + /** + * Apply filter by 'category_id' to product collection. + * + * For anchor categories, the products from all children categories will be present in the result. + * + * @param Filter $filter + * @param AbstractDb $collection + * @return bool Whether the filter is applied + * @throws LocalizedException + */ + public function apply(Filter $filter, AbstractDb $collection) + { + $conditionType = $filter->getConditionType(); + + if ($conditionType !== 'eq') { + throw new LocalizedException(__("'category_id' only supports 'eq' condition type.")); + } + + $categoryId = $filter->getValue(); + /** @var Collection $collection */ + $category = $this->categoryFactory->create(); + $this->categoryResourceModel->load($category, $categoryId); + $collection->addCategoryFilter($category); + + return true; + } +} diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 03631d049dafe..68a292ede6b4a 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -69,7 +69,7 @@ Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductPriceFilter Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductPriceFilter Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductPriceFilter - Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductCategoryFilter + Magento\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\CollectionProcessor\FilterProcessor\CategoryFilter diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index f9df24e8ff731..762861de94e67 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -278,7 +278,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ price: ProductPrices @doc(description: "A ProductPrices object, indicating the price of an item") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Price") gift_message_available: String @doc(description: "Indicates whether a gift message is available") manufacturer: Int @doc(description: "A number representing the product's manufacturer") - categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category") + categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") canonical_url: String @doc(description: "Canonical URL") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CanonicalUrl") } @@ -441,7 +441,7 @@ input ProductFilterInput @doc(description: "ProductFilterInput defines the filte min_price: FilterTypeInput @doc(description:"The numeric minimal price of the product. Do not include the currency code.") max_price: FilterTypeInput @doc(description:"The numeric maximal price of the product. Do not include the currency code.") special_price: FilterTypeInput @doc(description:"The numeric special price of the product. Do not include the currency code.") - category_ids: FilterTypeInput @doc(description: "An array of category IDs the product belongs to") + category_id: FilterTypeInput @doc(description: "Category ID the product belongs to") options_container: FilterTypeInput @doc(description: "If the product has multiple options, determines where they appear on the product page") required_options: FilterTypeInput @doc(description: "Indicates whether the product has required options") has_options: FilterTypeInput @doc(description: "Indicates whether additional attributes have been created for the product") diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 4d42330cd00bf..59009cc2d5637 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -10,6 +10,7 @@ use Magento\CatalogImportExport\Model\Import\Product\MediaGalleryProcessor; use Magento\CatalogImportExport\Model\Import\Product\ImageTypeProcessor; use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface as ValidatorInterface; +use Magento\CatalogInventory\Api\Data\StockItemInterface; use Magento\CatalogImportExport\Model\StockItemImporterInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\App\ObjectManager; @@ -2618,7 +2619,10 @@ private function _setStockUseConfigFieldsValues($rowData) { $useConfigFields = []; foreach ($rowData as $key => $value) { - $useConfigName = self::INVENTORY_USE_CONFIG_PREFIX . $key; + $useConfigName = $key === StockItemInterface::ENABLE_QTY_INCREMENTS + ? StockItemInterface::USE_CONFIG_ENABLE_QTY_INC + : self::INVENTORY_USE_CONFIG_PREFIX . $key; + if (isset($this->defaultStockData[$key]) && isset($this->defaultStockData[$useConfigName]) && !empty($value) @@ -2715,7 +2719,12 @@ protected function checkUrlKeyDuplicates() ); foreach ($urlKeyDuplicates as $entityData) { $rowNum = $this->rowNumbers[$entityData['store_id']][$entityData['request_path']]; - $this->addRowError(ValidatorInterface::ERROR_DUPLICATE_URL_KEY, $rowNum); + $message = sprintf( + $this->retrieveMessageTemplate(ValidatorInterface::ERROR_DUPLICATE_URL_KEY), + $entityData['request_path'], + $entityData['sku'] + ); + $this->addRowError(ValidatorInterface::ERROR_DUPLICATE_URL_KEY, $rowNum, 'url_key', $message); } } } diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php index 83defa64df250..c9ae6a96a3671 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php @@ -14,6 +14,14 @@ */ interface StockStatusInterface extends ExtensibleDataInterface { + /**#@+ + * Stock Status values. + */ + const STATUS_OUT_OF_STOCK = 0; + + const STATUS_IN_STOCK = 1; + /**#@-*/ + /**#@+ * Stock status object data keys */ diff --git a/app/code/Magento/CatalogInventory/Model/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/Stock/Status.php index 9a56c8e8804ec..899056d8f0835 100644 --- a/app/code/Magento/CatalogInventory/Model/Stock/Status.php +++ b/app/code/Magento/CatalogInventory/Model/Stock/Status.php @@ -17,14 +17,6 @@ */ class Status extends AbstractExtensibleModel implements StockStatusInterface { - /**#@+ - * Stock Status values - */ - const STATUS_OUT_OF_STOCK = 0; - - const STATUS_IN_STOCK = 1; - /**#@-*/ - /**#@+ * Field name */ diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php index 3d9dcd05f8fac..d049d74bd2601 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php @@ -32,7 +32,7 @@ public function __construct(Context $context, Registry $coreRegistry) /** * Initialize category object in registry * - * @return Category + * @return Category|bool */ protected function _initCategory() { diff --git a/app/code/Magento/CatalogRule/etc/db_schema.xml b/app/code/Magento/CatalogRule/etc/db_schema.xml index 883a992d8c730..f4c40a6930cc0 100644 --- a/app/code/Magento/CatalogRule/etc/db_schema.xml +++ b/app/code/Magento/CatalogRule/etc/db_schema.xml @@ -60,7 +60,7 @@ - + @@ -198,7 +198,7 @@ - + diff --git a/app/code/Magento/CatalogRule/etc/db_schema_whitelist.json b/app/code/Magento/CatalogRule/etc/db_schema_whitelist.json index a41d31a08ee29..f5aaece43f179 100644 --- a/app/code/Magento/CatalogRule/etc/db_schema_whitelist.json +++ b/app/code/Magento/CatalogRule/etc/db_schema_whitelist.json @@ -49,7 +49,8 @@ }, "constraint": { "PRIMARY": true, - "IDX_EAA51B56FF092A0DCB795D1CEF812B7B": true + "IDX_EAA51B56FF092A0DCB795D1CEF812B7B": true, + "UNQ_EAA51B56FF092A0DCB795D1CEF812B7B": true } }, "catalogrule_product_price": { @@ -146,7 +147,8 @@ }, "constraint": { "PRIMARY": true, - "UNQ_BDF2B92A4F0B28D7896648B3B8A26089": true + "IDX_EAA51B56FF092A0DCB795D1CEF812B7B": true, + "UNQ_EAA51B56FF092A0DCB795D1CEF812B7B": true } }, "catalogrule_product_price_replica": { @@ -190,4 +192,4 @@ "PRIMARY": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php index cd419902831b8..5ad2635576857 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -221,7 +221,7 @@ private function getSelectForSearchableProducts( $lastProductId, $batch ) { - $websiteId = $this->storeManager->getStore($storeId)->getWebsiteId(); + $websiteId = (int)$this->storeManager->getStore($storeId)->getWebsiteId(); $lastProductId = (int) $lastProductId; $select = $this->connection->select() diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php index ffba417eb3ac7..fac8c4d2a47f6 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php @@ -120,7 +120,7 @@ public function processAttributeValue($attribute, $value) * * @param array $index * @param string $separator - * @return string + * @return array */ public function prepareEntityIndex($index, $separator = ' ') { diff --git a/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php b/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php index d93475a4744ca..de996bed02439 100644 --- a/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php +++ b/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php @@ -394,9 +394,9 @@ protected function orderCountryOptions(array $countryOptions) ]]; foreach ($countryOptions as $countryOption) { if (empty($countryOption['value']) || in_array($countryOption['value'], $this->topCountryCodes)) { - array_push($headOptions, $countryOption); + $headOptions[] = $countryOption; } else { - array_push($tailOptions, $countryOption); + $tailOptions[] = $countryOption; } } return array_merge($headOptions, $tailOptions); diff --git a/app/code/Magento/Checkout/Block/Checkout/DirectoryDataProcessor.php b/app/code/Magento/Checkout/Block/Checkout/DirectoryDataProcessor.php index 1d5bb5bb07d81..587dd06d89106 100644 --- a/app/code/Magento/Checkout/Block/Checkout/DirectoryDataProcessor.php +++ b/app/code/Magento/Checkout/Block/Checkout/DirectoryDataProcessor.php @@ -141,9 +141,9 @@ private function orderCountryOptions(array $countryOptions) ]]; foreach ($countryOptions as $countryOption) { if (empty($countryOption['value']) || in_array($countryOption['value'], $topCountryCodes)) { - array_push($headOptions, $countryOption); + $headOptions[] = $countryOption; } else { - array_push($tailOptions, $countryOption); + $tailOptions[] = $countryOption; } } return array_merge($headOptions, $tailOptions); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js index a0bdf0a17d7fe..aba0c31b998d1 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js @@ -14,20 +14,17 @@ define([ 'use strict'; var quoteItems = ko.observable(quote.totals().items), - cartData = customerData.get('cart'); + cartData = customerData.get('cart'), + quoteSubtotal = parseFloat(quote.totals().subtotal), + subtotalAmount = parseFloat(cartData().subtotalAmount); quote.totals.subscribe(function (newValue) { quoteItems(newValue.items); }); - cartData.subscribe(function () { - var quoteSubtotal = parseFloat(quote.totals().subtotal), - subtotalAmount = parseFloat(cartData().subtotalAmount); - - if (quoteSubtotal !== subtotalAmount) { - customerData.reload(['cart'], false); - } - }, this); + if (quoteSubtotal !== subtotalAmount) { + customerData.reload(['cart'], false); + } return { totals: quote.totals, diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js index 33223e9ae3c24..a2f8c8c56ff33 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js @@ -94,10 +94,6 @@ define([ this.isLoading(addToCartCalls > 0); sidebarInitialized = false; this.update(updatedCart); - - if (cartData()['website_id'] !== window.checkout.websiteId) { - customerData.reload(['cart'], false); - } initSidebar(); }, this); $('[data-block="minicart"]').on('contentLoading', function () { @@ -105,6 +101,10 @@ define([ self.isLoading(true); }); + if (cartData()['website_id'] !== window.checkout.websiteId) { + customerData.reload(['cart'], false); + } + return this._super(); }, isLoading: ko.observable(false), diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js index 37b7c7c41b216..558a1fdf31085 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js @@ -26,7 +26,7 @@ define([ if (!(data && data.items && data.items.length && productId)) { return false; } - changedProductOptions = data.items.find(function (item) { + changedProductOptions = _.find(data.items, function (item) { if (item['item_id'] === itemId) { return item['product_id'] === productId; } diff --git a/app/code/Magento/Customer/Block/Widget/Dob.php b/app/code/Magento/Customer/Block/Widget/Dob.php index e456efbc605fa..1a1d5d81bf13d 100644 --- a/app/code/Magento/Customer/Block/Widget/Dob.php +++ b/app/code/Magento/Customer/Block/Widget/Dob.php @@ -127,7 +127,8 @@ protected function getFormFilter() protected function applyOutputFilter($value) { $filter = $this->getFormFilter(); - if ($filter) { + if ($filter && $value) { + $value = date('Y-m-d', $this->getTime()); $value = $filter->outputFilter($value); } return $value; diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 4fc74fa695829..63eb1efa64be6 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -624,6 +624,7 @@ public function resetPassword($email, $resetToken, $newPassword) $customerSecure->setRpToken(null); $customerSecure->setRpTokenCreatedAt(null); $customerSecure->setPasswordHash($this->createPasswordHash($newPassword)); + $this->getAuthentication()->unlock($customer->getId()); $this->sessionManager->destroy(); $this->destroyCustomerSessions($customer->getId()); $this->customerRepository->save($customer); diff --git a/app/code/Magento/Customer/Model/Address/Validator/Country.php b/app/code/Magento/Customer/Model/Address/Validator/Country.php index 0ba8a21ff8cd9..ff1020eba70ef 100644 --- a/app/code/Magento/Customer/Model/Address/Validator/Country.php +++ b/app/code/Magento/Customer/Model/Address/Validator/Country.php @@ -7,6 +7,8 @@ use Magento\Customer\Model\Address\AbstractAddress; use Magento\Customer\Model\Address\ValidatorInterface; +use Magento\Framework\App\ObjectManager; +use Magento\Store\Model\ScopeInterface; /** * Address country and region validator. @@ -18,13 +20,31 @@ class Country implements ValidatorInterface */ private $directoryData; + /** + * @var \Magento\Directory\Model\AllowedCountries + */ + private $allowedCountriesReader; + + /** + * @var \Magento\Customer\Model\Config\Share + */ + private $shareConfig; + /** * @param \Magento\Directory\Helper\Data $directoryData + * @param \Magento\Directory\Model\AllowedCountries|null $allowedCountriesReader + * @param \Magento\Customer\Model\Config\Share|null $shareConfig */ public function __construct( - \Magento\Directory\Helper\Data $directoryData + \Magento\Directory\Helper\Data $directoryData, + \Magento\Directory\Model\AllowedCountries $allowedCountriesReader = null, + \Magento\Customer\Model\Config\Share $shareConfig = null ) { $this->directoryData = $directoryData; + $this->allowedCountriesReader = $allowedCountriesReader + ?: ObjectManager::getInstance()->get(\Magento\Directory\Model\AllowedCountries::class); + $this->shareConfig = $shareConfig + ?: ObjectManager::getInstance()->get(\Magento\Customer\Model\Config\Share::class); } /** @@ -52,7 +72,7 @@ private function validateCountry(AbstractAddress $address) $errors = []; if (!\Zend_Validate::is($countryId, 'NotEmpty')) { $errors[] = __('"%fieldName" is required. Enter and try again.', ['fieldName' => 'countryId']); - } elseif (!in_array($countryId, $this->directoryData->getCountryCollection()->getAllIds(), true)) { + } elseif (!in_array($countryId, $this->getWebsiteAllowedCountries($address), true)) { //Checking if such country exists. $errors[] = __( 'Invalid value of "%value" provided for the %fieldName field.', @@ -97,4 +117,21 @@ private function validateRegion(AbstractAddress $address) return $errors; } + + /** + * Return allowed counties per website. + * + * @param AbstractAddress $address + * @return array + */ + private function getWebsiteAllowedCountries(AbstractAddress $address): array + { + $websiteId = null; + + if (!$this->shareConfig->isGlobalScope()) { + $websiteId = $address->getCustomer() ? $address->getCustomer()->getWebsiteId() : null; + } + + return $this->allowedCountriesReader->getAllowedCountries(ScopeInterface::SCOPE_WEBSITE, $websiteId); + } } diff --git a/app/code/Magento/Customer/Test/Unit/Model/Address/Validator/CountryTest.php b/app/code/Magento/Customer/Test/Unit/Model/Address/Validator/CountryTest.php index e70f93edab12c..9ab35f2d301d4 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Address/Validator/CountryTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Address/Validator/CountryTest.php @@ -6,6 +6,8 @@ namespace Magento\Customer\Test\Unit\Model\Address\Validator; +use Magento\Store\Model\ScopeInterface; + /** * Magento\Customer\Model\Address\Validator\Country tests. */ @@ -20,14 +22,34 @@ class CountryTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ private $objectManager; + /** + * @var \Magento\Directory\Model\AllowedCountries|\PHPUnit_Framework_MockObject_MockObject + */ + private $allowedCountriesReaderMock; + + /** + * @var \Magento\Customer\Model\Config\Share|\PHPUnit_Framework_MockObject_MockObject + */ + private $shareConfigMock; + protected function setUp() { $this->directoryDataMock = $this->createMock(\Magento\Directory\Helper\Data::class); $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->allowedCountriesReaderMock = $this->createPartialMock( + \Magento\Directory\Model\AllowedCountries::class, + ['getAllowedCountries'] + ); + $this->shareConfigMock = $this->createPartialMock( + \Magento\Customer\Model\Config\Share::class, + ['isGlobalScope'] + ); $this->model = $this->objectManager->getObject( \Magento\Customer\Model\Address\Validator\Country::class, [ 'directoryData' => $this->directoryDataMock, + 'allowedCountriesReader' => $this->allowedCountriesReaderMock, + 'shareConfig' => $this->shareConfigMock, ] ); } @@ -59,16 +81,11 @@ public function testValidate(array $data, array $countryIds, array $allowedRegio ->method('isRegionRequired') ->willReturn($data['regionRequired']); - $countryCollectionMock = $this->getMockBuilder(\Magento\Directory\Model\ResourceModel\Country\Collection::class) - ->disableOriginalConstructor() - ->setMethods(['getAllIds']) - ->getMock(); - - $this->directoryDataMock->expects($this->any()) - ->method('getCountryCollection') - ->willReturn($countryCollectionMock); - - $countryCollectionMock->expects($this->any())->method('getAllIds')->willReturn($countryIds); + $this->shareConfigMock->method('isGlobalScope')->willReturn(false); + $this->allowedCountriesReaderMock + ->method('getAllowedCountries') + ->with(ScopeInterface::SCOPE_WEBSITE, null) + ->willReturn($countryIds); $addressMock->method('getCountryId')->willReturn($data['country_id']); diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index 0d99c1145e81b..86ed633790491 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -353,9 +353,9 @@ - customer_group_code - customer_group_id - class_name + main_table.customer_group_code + main_table.customer_group_id + tax_class_table.class_name @@ -363,9 +363,9 @@ - customer_group_code - customer_group_id - class_name + main_table.customer_group_code + main_table.customer_group_id + tax_class_table.class_name ASC diff --git a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml index 77e250c5de923..2d44dde215139 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml @@ -24,7 +24,7 @@
@@ -43,12 +43,3 @@
- diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index 43e4e92fd0904..6cdb8fc44f665 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -131,7 +131,7 @@
- +
diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml index 73e9c4fa34bb3..223e43c9bb897 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml @@ -28,9 +28,7 @@ $suffix = $block->showSuffix(); ?> getNoWrap()): ?>
- +
@@ -38,10 +36,7 @@ $suffix = $block->showSuffix();
- - +
getPrefixOptions() === false): ?> showSuffix();
- - +
showSuffix(); isMiddlenameRequired(); ?>
- - +
showSuffix();
- - +
showSuffix();
- - +
getSuffixOptions() === false): ?>
diff --git a/app/code/Magento/Deploy/Package/Processor/PreProcessor/Less.php b/app/code/Magento/Deploy/Package/Processor/PreProcessor/Less.php index 8a464ca4bc627..b5fe0c78640e5 100644 --- a/app/code/Magento/Deploy/Package/Processor/PreProcessor/Less.php +++ b/app/code/Magento/Deploy/Package/Processor/PreProcessor/Less.php @@ -188,7 +188,7 @@ private function buildMap($filePath, $packagePath, $contentType) if (!isset($this->map[$filePath])) { $this->map[$filePath] = []; } - array_push($this->map[$filePath], $resolvedMapPath); + $this->map[$filePath][] = $resolvedMapPath; $this->buildMap($resolvedMapPath, $packagePath, $contentType); }; if ($content) { diff --git a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php index 6715ecd681efe..776bef99e7960 100644 --- a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php +++ b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php @@ -22,11 +22,6 @@ */ class TablesWhitelistGenerateCommand extends Command { - /** - * Whitelist file name. - */ - const GENERATED_FILE_NAME = 'db_schema_whitelist.json'; - /** * Module name key, that will be used in whitelist generate command. */ diff --git a/app/code/Magento/Developer/Model/Logger/Handler/Syslog.php b/app/code/Magento/Developer/Model/Logger/Handler/Syslog.php new file mode 100644 index 0000000000000..6dc276a696f6f --- /dev/null +++ b/app/code/Magento/Developer/Model/Logger/Handler/Syslog.php @@ -0,0 +1,59 @@ +scopeConfig = $scopeConfig; + $this->deploymentConfig = $deploymentConfig; + } + + /** + * @inheritdoc + */ + public function isHandling(array $record): bool + { + return parent::isHandling($record) + && $this->deploymentConfig->isAvailable() + && $this->scopeConfig->getValue(self::CONFIG_PATH); + } +} diff --git a/app/code/Magento/Developer/Test/Unit/Model/Logger/Handler/SyslogTest.php b/app/code/Magento/Developer/Test/Unit/Model/Logger/Handler/SyslogTest.php new file mode 100644 index 0000000000000..c744645b670b4 --- /dev/null +++ b/app/code/Magento/Developer/Test/Unit/Model/Logger/Handler/SyslogTest.php @@ -0,0 +1,103 @@ +scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class); + $this->deploymentConfigMock = $this->createMock(DeploymentConfig::class); + + $this->model = new Syslog( + $this->scopeConfigMock, + $this->deploymentConfigMock, + 'Magento' + ); + } + + public function testIsHandling(): void + { + $record = [ + 'level' => Monolog::DEBUG, + ]; + + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with(Syslog::CONFIG_PATH) + ->willReturn('1'); + $this->deploymentConfigMock->expects($this->once()) + ->method('isAvailable') + ->willReturn(true); + + $this->assertTrue( + $this->model->isHandling($record) + ); + } + + public function testIsHandlingNotInstalled(): void + { + $record = [ + 'level' => Monolog::DEBUG, + ]; + + $this->scopeConfigMock->expects($this->never()) + ->method('getValue'); + $this->deploymentConfigMock->expects($this->once()) + ->method('isAvailable') + ->willReturn(false); + + $this->assertFalse( + $this->model->isHandling($record) + ); + } + + public function testIsHandlingDisabled(): void + { + $record = [ + 'level' => Monolog::DEBUG, + ]; + + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with(Syslog::CONFIG_PATH) + ->willReturn('0'); + $this->deploymentConfigMock->expects($this->once()) + ->method('isAvailable') + ->willReturn(true); + + $this->assertFalse( + $this->model->isHandling($record) + ); + } +} diff --git a/app/code/Magento/Developer/etc/adminhtml/system.xml b/app/code/Magento/Developer/etc/adminhtml/system.xml index 9663cff72bc9d..aae9913009837 100644 --- a/app/code/Magento/Developer/etc/adminhtml/system.xml +++ b/app/code/Magento/Developer/etc/adminhtml/system.xml @@ -32,6 +32,13 @@ Magento\Config\Model\Config\Source\Yesno + + + + + Magento\Config\Model\Config\Source\Yesno + + diff --git a/app/code/Magento/Developer/etc/di.xml b/app/code/Magento/Developer/etc/di.xml index 2254c94a8a913..21ecf10c1b1e7 100644 --- a/app/code/Magento/Developer/etc/di.xml +++ b/app/code/Magento/Developer/etc/di.xml @@ -7,6 +7,7 @@ --> + diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php index 2ed8ed8893dfb..a352c4bdf7bc3 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php @@ -230,6 +230,7 @@ protected function getTitleColumn() 'formElement' => Container::NAME, 'component' => 'Magento_Ui/js/form/components/group', 'label' => __('Title'), + 'showLabel' => false, 'dataScope' => '', ]; $titleField['arguments']['data']['config'] = [ @@ -255,6 +256,7 @@ protected function getPriceColumn() 'formElement' => Container::NAME, 'component' => 'Magento_Ui/js/form/components/group', 'label' => __('Price'), + 'showLabel' => false, 'dataScope' => '', ]; $priceField['arguments']['data']['config'] = [ @@ -288,6 +290,7 @@ protected function getFileColumn() 'formElement' => Container::NAME, 'component' => 'Magento_Ui/js/form/components/group', 'label' => __('File'), + 'showLabel' => false, 'dataScope' => '', ]; $fileTypeField['arguments']['data']['config'] = [ @@ -350,6 +353,7 @@ protected function getSampleColumn() 'formElement' => Container::NAME, 'component' => 'Magento_Ui/js/form/components/group', 'label' => __('Sample'), + 'showLabel' => false, 'dataScope' => '', ]; $sampleTypeField['arguments']['data']['config'] = [ @@ -425,6 +429,7 @@ protected function getMaxDownloadsColumn() 'formElement' => Container::NAME, 'component' => 'Magento_Ui/js/form/components/group', 'label' => __('Max. Downloads'), + 'showLabel' => false, 'dataScope' => '', ]; $numberOfDownloadsField['arguments']['data']['config'] = [ diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php index 178420c62a020..1587163ba8121 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php @@ -200,6 +200,7 @@ protected function getTitleColumn() 'componentType' => Container::NAME, 'formElement' => Container::NAME, 'component' => 'Magento_Ui/js/form/components/group', + 'showLabel' => false, 'label' => __('Title'), 'dataScope' => '', ]; @@ -226,6 +227,7 @@ protected function getSampleColumn() 'formElement' => Container::NAME, 'component' => 'Magento_Ui/js/form/components/group', 'label' => __('File'), + 'showLabel' => false, 'dataScope' => '', ]; $sampleType['arguments']['data']['config'] = [ diff --git a/app/code/Magento/Eav/etc/db_schema.xml b/app/code/Magento/Eav/etc/db_schema.xml index 24a9d405dd7a5..f930321e5259b 100644 --- a/app/code/Magento/Eav/etc/db_schema.xml +++ b/app/code/Magento/Eav/etc/db_schema.xml @@ -377,7 +377,7 @@ - + diff --git a/app/code/Magento/Eav/etc/db_schema_whitelist.json b/app/code/Magento/Eav/etc/db_schema_whitelist.json index 9c015e0e3b8c5..cf06b06d833d5 100644 --- a/app/code/Magento/Eav/etc/db_schema_whitelist.json +++ b/app/code/Magento/Eav/etc/db_schema_whitelist.json @@ -234,6 +234,7 @@ "PRIMARY": true, "EAV_ATTR_GROUP_ATTR_SET_ID_EAV_ATTR_SET_ATTR_SET_ID": true, "EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_NAME": true, + "EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_CODE": true, "CATALOG_CATEGORY_PRODUCT_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_CODE": true } }, @@ -386,4 +387,4 @@ "EAV_FORM_ELEMENT_TYPE_ID_ATTRIBUTE_ID": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/Elasticsearch/Model/Config.php b/app/code/Magento/Elasticsearch/Model/Config.php index 93e715f928047..a0f3b6433b43b 100644 --- a/app/code/Magento/Elasticsearch/Model/Config.php +++ b/app/code/Magento/Elasticsearch/Model/Config.php @@ -6,6 +6,8 @@ namespace Magento\Elasticsearch\Model; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Search\EngineResolverInterface; +use Magento\Search\Model\EngineResolver; use Magento\Store\Model\ScopeInterface; use Magento\AdvancedSearch\Model\Client\ClientOptionsInterface; use Magento\AdvancedSearch\Model\Client\ClientResolver; @@ -54,21 +56,28 @@ class Config implements ClientOptionsInterface */ private $clientResolver; + /** + * @var EngineResolverInterface + */ + private $engineResolver; + /** * Constructor * * @param ScopeConfigInterface $scopeConfig - * @param ClientResolver $clientResolver - * @param string $prefix + * @param ClientResolver|null $clientResolver + * @param EngineResolverInterface|null $engineResolver + * @param string|null $prefix */ public function __construct( ScopeConfigInterface $scopeConfig, ClientResolver $clientResolver = null, + EngineResolverInterface $engineResolver = null, $prefix = null ) { $this->scopeConfig = $scopeConfig; - $this->clientResolver = $clientResolver ?: - ObjectManager::getInstance()->get(ClientResolver::class); + $this->clientResolver = $clientResolver ?: ObjectManager::getInstance()->get(ClientResolver::class); + $this->engineResolver = $engineResolver ?: ObjectManager::getInstance()->get(EngineResolverInterface::class); $this->prefix = $prefix ?: $this->clientResolver->getCurrentEngine(); } @@ -126,7 +135,7 @@ public function getSearchConfigData($field, $storeId = null) */ public function isElasticsearchEnabled() { - return $this->getSearchConfigData('engine') == self::ENGINE_NAME; + return $this->engineResolver->getCurrentSearchEngine() === self::ENGINE_NAME; } /** diff --git a/app/code/Magento/Elasticsearch/Model/Indexer/Plugin/DependencyUpdaterPlugin.php b/app/code/Magento/Elasticsearch/Model/Indexer/Plugin/DependencyUpdaterPlugin.php new file mode 100644 index 0000000000000..f1b153c98b2af --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Indexer/Plugin/DependencyUpdaterPlugin.php @@ -0,0 +1,85 @@ +config = $config; + } + + /** + * Remove index dependency, if it needed, on run reindexing by specifics indexes. + * + * @param Provider $provider + * @param array $dependencies + * @param string $indexerId + * @return array + * @see \Magento\Indexer\Console\Command\IndexerReindexCommand::getIndexers() + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterGetIndexerIdsToRunBefore(Provider $provider, array $dependencies, string $indexerId): array + { + if ($this->isFilteringNeeded($indexerId, CatalogSearchFulltextIndexer::INDEXER_ID)) { + $dependencies = array_diff($dependencies, [CatalogInventoryStockIndexer::INDEXER_ID]); + } + + return $dependencies; + } + + /** + * Remove index dependency, if it needed, on reindex triggers. + * + * @param Provider $provider + * @param array $dependencies + * @param string $indexerId + * @return array + * @see \Magento\Indexer\Model\Indexer\DependencyDecorator + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterGetIndexerIdsToRunAfter(Provider $provider, array $dependencies, string $indexerId): array + { + if ($this->isFilteringNeeded($indexerId, CatalogInventoryStockIndexer::INDEXER_ID)) { + $dependencies = array_diff($dependencies, [CatalogSearchFulltextIndexer::INDEXER_ID]); + } + + return $dependencies; + } + + /** + * @param string $currentIndexerId + * @param string $targetIndexerId + * @return bool + */ + private function isFilteringNeeded(string $currentIndexerId, string $targetIndexerId): bool + { + return (!$this->config->isElasticsearchEnabled() && $targetIndexerId === $currentIndexerId); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Indexer/Plugin/StockedProductsFilterPlugin.php b/app/code/Magento/Elasticsearch/Model/Indexer/Plugin/StockedProductsFilterPlugin.php new file mode 100644 index 0000000000000..ec18b955a2917 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Indexer/Plugin/StockedProductsFilterPlugin.php @@ -0,0 +1,94 @@ +config = $config; + $this->stockConfiguration = $stockConfiguration; + $this->stockStatusRepository = $stockStatusRepository; + $this->stockStatusCriteriaFactory = $stockStatusCriteriaFactory; + } + + /** + * Filter out of stock options for configurable product. + * + * @param DataProvider $dataProvider + * @param array $indexData + * @param array $productData + * @param int $storeId + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforePrepareProductIndex( + DataProvider $dataProvider, + array $indexData, + array $productData, + int $storeId + ): array { + if ($this->config->isElasticsearchEnabled() && !$this->stockConfiguration->isShowOutOfStock($storeId)) { + $productIds = array_keys($indexData); + $stockStatusCriteria = $this->stockStatusCriteriaFactory->create(); + $stockStatusCriteria->setProductsFilter($productIds); + $stockStatusCollection = $this->stockStatusRepository->getList($stockStatusCriteria); + $stockStatuses = $stockStatusCollection->getItems(); + $stockStatuses = array_filter($stockStatuses, function (StockStatusInterface $stockStatus) { + return StockStatusInterface::STATUS_IN_STOCK == $stockStatus->getStockStatus(); + }); + $indexData = array_intersect_key($indexData, $stockStatuses); + } + + return [ + $indexData, + $productData, + $storeId, + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Indexer/Plugin/DependencyUpdaterPluginTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Indexer/Plugin/DependencyUpdaterPluginTest.php new file mode 100644 index 0000000000000..15510843b0e60 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Indexer/Plugin/DependencyUpdaterPluginTest.php @@ -0,0 +1,87 @@ +configMock = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->getMock(); + $this->configMock->expects($this->exactly(2)) + ->method('isElasticsearchEnabled') + ->willReturnOnConsecutiveCalls(true, false); + $this->providerMock = $this->getMockBuilder(DependencyInfoProvider::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->plugin = new DependencyUpdaterPlugin($this->configMock); + } + + /** + * @return void + */ + public function testAfterGetIndexerIdsToRunBefore(): void + { + $dependencies = [ + CatalogInventoryStockIndexer::INDEXER_ID, + ]; + $indexerId = CatalogSearchFulltextIndexer::INDEXER_ID; + + $indexerIds = $this->plugin->afterGetIndexerIdsToRunBefore($this->providerMock, $dependencies, $indexerId); + $this->assertContains(CatalogInventoryStockIndexer::INDEXER_ID, $indexerIds); + + $indexerIds = $this->plugin->afterGetIndexerIdsToRunBefore($this->providerMock, $dependencies, $indexerId); + $this->assertNotContains(CatalogInventoryStockIndexer::INDEXER_ID, $indexerIds); + } + + /** + * @return void + */ + public function testAfterGetIndexerIdsToRunAfter(): void + { + $dependencies = [ + CatalogSearchFulltextIndexer::INDEXER_ID, + ]; + $indexerId = CatalogInventoryStockIndexer::INDEXER_ID; + + $indexerIds = $this->plugin->afterGetIndexerIdsToRunAfter($this->providerMock, $dependencies, $indexerId); + $this->assertContains(CatalogSearchFulltextIndexer::INDEXER_ID, $indexerIds); + + $indexerIds = $this->plugin->afterGetIndexerIdsToRunAfter($this->providerMock, $dependencies, $indexerId); + $this->assertNotContains(CatalogSearchFulltextIndexer::INDEXER_ID, $indexerIds); + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php new file mode 100644 index 0000000000000..f66d2532b32ae --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php @@ -0,0 +1,134 @@ +configMock = $this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock(); + $this->stockConfigurationMock = $this->getMockBuilder(StockConfigurationInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->stockStatusRepositoryMock = $this->getMockBuilder(StockStatusRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->stockStatusCriteriaFactoryMock = $this->getMockBuilder(StockStatusCriteriaInterfaceFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->plugin = new StockedProductsFilterPlugin( + $this->configMock, + $this->stockConfigurationMock, + $this->stockStatusRepositoryMock, + $this->stockStatusCriteriaFactoryMock + ); + } + + /** + * @return void + */ + public function testBeforePrepareProductIndex(): void + { + /** @var DataProvider|\PHPUnit_Framework_MockObject_MockObject $dataProviderMock */ + $dataProviderMock = $this->getMockBuilder(DataProvider::class)->disableOriginalConstructor()->getMock(); + $indexData = [ + 1 => [], + 2 => [], + ]; + $productData = []; + $storeId = 1; + + $this->configMock + ->expects($this->once()) + ->method('isElasticsearchEnabled') + ->willReturn(true); + $this->stockConfigurationMock + ->expects($this->once()) + ->method('isShowOutOfStock') + ->willReturn(false); + + $stockStatusCriteriaMock = $this->getMockBuilder(StockStatusCriteriaInterface::class)->getMock(); + $stockStatusCriteriaMock + ->expects($this->once()) + ->method('setProductsFilter') + ->willReturn(true); + $this->stockStatusCriteriaFactoryMock + ->expects($this->once()) + ->method('create') + ->willReturn($stockStatusCriteriaMock); + + $stockStatusMock = $this->getMockBuilder(StockStatusInterface::class)->getMock(); + $stockStatusMock->expects($this->atLeastOnce()) + ->method('getStockStatus') + ->willReturnOnConsecutiveCalls(Stock::STOCK_IN_STOCK, Stock::STOCK_OUT_OF_STOCK); + $stockStatusCollectionMock = $this->getMockBuilder(StockStatusCollectionInterface::class)->getMock(); + $stockStatusCollectionMock + ->expects($this->once()) + ->method('getItems') + ->willReturn([ + 1 => $stockStatusMock, + 2 => $stockStatusMock, + ]); + $this->stockStatusRepositoryMock + ->expects($this->once()) + ->method('getList') + ->willReturn($stockStatusCollectionMock); + + list ($indexData, $productData, $storeId) = $this->plugin->beforePrepareProductIndex( + $dataProviderMock, + $indexData, + $productData, + $storeId + ); + + $this->assertEquals([1], array_keys($indexData)); + } +} diff --git a/app/code/Magento/Elasticsearch/composer.json b/app/code/Magento/Elasticsearch/composer.json index 8e379579641d3..a6b4f93ade579 100644 --- a/app/code/Magento/Elasticsearch/composer.json +++ b/app/code/Magento/Elasticsearch/composer.json @@ -10,6 +10,7 @@ "magento/module-eav": "*", "magento/module-search": "*", "magento/module-store": "*", + "magento/module-catalog-inventory": "*", "magento/framework": "*", "elasticsearch/elasticsearch": "~2.0|~5.1" }, diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index b3ba240ae239c..2d569eecfee58 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -189,6 +189,12 @@ + + + + + + diff --git a/app/code/Magento/Elasticsearch/etc/indexer.xml b/app/code/Magento/Elasticsearch/etc/indexer.xml new file mode 100644 index 0000000000000..245829396a67b --- /dev/null +++ b/app/code/Magento/Elasticsearch/etc/indexer.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/app/code/Magento/ImportExport/Model/Report/Csv.php b/app/code/Magento/ImportExport/Model/Report/Csv.php index 86c68d7c4df77..7279092265cbb 100644 --- a/app/code/Magento/ImportExport/Model/Report/Csv.php +++ b/app/code/Magento/ImportExport/Model/Report/Csv.php @@ -77,7 +77,7 @@ public function createReport( $outputCsv = $this->createOutputCsvModel($outputFileName); $columnsName = $sourceCsv->getColNames(); - array_push($columnsName, self::REPORT_ERROR_COLUMN_NAME); + $columnsName[] = self::REPORT_ERROR_COLUMN_NAME; $outputCsv->setHeaderCols($columnsName); foreach ($sourceCsv as $rowNum => $rowData) { diff --git a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php index 70d480a448638..9412b13895599 100644 --- a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php +++ b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php @@ -170,6 +170,11 @@ class Multishipping extends \Magento\Framework\DataObject */ private $logger; + /** + * @var \Magento\Framework\Api\DataObjectHelper + */ + private $dataObjectHelper; + /** * Constructor * @@ -227,7 +232,8 @@ public function __construct( \Magento\Quote\Api\Data\CartExtensionFactory $cartExtensionFactory = null, AllowedCountries $allowedCountryReader = null, Multishipping\PlaceOrderFactory $placeOrderFactory = null, - LoggerInterface $logger = null + LoggerInterface $logger = null, + \Magento\Framework\Api\DataObjectHelper $dataObjectHelper = null ) { $this->_eventManager = $eventManager; $this->_scopeConfig = $scopeConfig; @@ -258,6 +264,8 @@ public function __construct( ->get(Multishipping\PlaceOrderFactory::class); $this->logger = $logger ?: ObjectManager::getInstance() ->get(LoggerInterface::class); + $this->dataObjectHelper = $dataObjectHelper ?: ObjectManager::getInstance() + ->get(\Magento\Framework\Api\DataObjectHelper::class); parent::__construct($data); $this->_init(); } @@ -670,7 +678,14 @@ protected function _prepareOrder(\Magento\Quote\Model\Quote\Address $address) $quote->reserveOrderId(); $quote->collectTotals(); - $order = $this->quoteAddressToOrder->convert($address); + $order = $this->_orderFactory->create(); + + $this->dataObjectHelper->mergeDataObjects( + \Magento\Sales\Api\Data\OrderInterface::class, + $order, + $this->quoteAddressToOrder->convert($address) + ); + $order->setQuote($quote); $order->setBillingAddress($this->quoteAddressToOrderAddress->convert($quote->getBillingAddress())); diff --git a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php index b2e484e148f43..94c11bef1d311 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php @@ -11,7 +11,9 @@ use Magento\Customer\Api\Data\AddressInterface; use Magento\Customer\Api\Data\AddressSearchResultsInterface; use Magento\Customer\Api\Data\CustomerInterface; -use Magento\Customer\Model\Data\Address; +use Magento\Multishipping\Model\Checkout\Type\Multishipping\PlaceOrderDefault; +use Magento\Multishipping\Model\Checkout\Type\Multishipping\PlaceOrderFactory; +use Magento\Quote\Model\Quote\Address; use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\SearchCriteria; @@ -51,6 +53,7 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) */ class MultishippingTest extends \PHPUnit\Framework\TestCase { @@ -119,24 +122,69 @@ class MultishippingTest extends \PHPUnit\Framework\TestCase */ private $quoteRepositoryMock; + /** + * @var OrderFactory|PHPUnit_Framework_MockObject_MockObject + */ + private $orderFactoryMock; + + /** + * @var \Magento\Framework\Api\DataObjectHelper|PHPUnit_Framework_MockObject_MockObject + */ + private $dataObjectHelperMock; + + /** + * @var ToOrder|PHPUnit_Framework_MockObject_MockObject + */ + private $toOrderMock; + + /** + * @var ToOrderAddress|PHPUnit_Framework_MockObject_MockObject + */ + private $toOrderAddressMock; + + /** + * @var ToOrderPayment|PHPUnit_Framework_MockObject_MockObject + */ + private $toOrderPaymentMock; + + /** + * @var PriceCurrencyInterface|PHPUnit_Framework_MockObject_MockObject + */ + private $priceMock; + + /** + * @var ToOrderItem|PHPUnit_Framework_MockObject_MockObject + */ + private $toOrderItemMock; + + /** + * @var PlaceOrderFactory|PHPUnit_Framework_MockObject_MockObject + */ + private $placeOrderFactoryMock; + + /** + * @var Generic|PHPUnit_Framework_MockObject_MockObject + */ + private $sessionMock; + protected function setUp() { $this->checkoutSessionMock = $this->createSimpleMock(Session::class); $this->customerSessionMock = $this->createSimpleMock(CustomerSession::class); - $orderFactoryMock = $this->createSimpleMock(OrderFactory::class); + $this->orderFactoryMock = $this->createSimpleMock(OrderFactory::class); $eventManagerMock = $this->createSimpleMock(ManagerInterface::class); $scopeConfigMock = $this->createSimpleMock(ScopeConfigInterface::class); - $sessionMock = $this->createSimpleMock(Generic::class); + $this->sessionMock = $this->createSimpleMock(Generic::class); $addressFactoryMock = $this->createSimpleMock(AddressFactory::class); - $toOrderMock = $this->createSimpleMock(ToOrder::class); - $toOrderAddressMock = $this->createSimpleMock(ToOrderAddress::class); - $toOrderPaymentMock = $this->createSimpleMock(ToOrderPayment::class); - $toOrderItemMock = $this->createSimpleMock(ToOrderItem::class); + $this->toOrderMock = $this->createSimpleMock(ToOrder::class); + $this->toOrderAddressMock = $this->createSimpleMock(ToOrderAddress::class); + $this->toOrderPaymentMock = $this->createSimpleMock(ToOrderPayment::class); + $this->toOrderItemMock = $this->createSimpleMock(ToOrderItem::class); $storeManagerMock = $this->createSimpleMock(StoreManagerInterface::class); $paymentSpecMock = $this->createSimpleMock(SpecificationInterface::class); $this->helperMock = $this->createSimpleMock(Data::class); $orderSenderMock = $this->createSimpleMock(OrderSender::class); - $priceMock = $this->createSimpleMock(PriceCurrencyInterface::class); + $this->priceMock = $this->createSimpleMock(PriceCurrencyInterface::class); $this->quoteRepositoryMock = $this->createSimpleMock(CartRepositoryInterface::class); $this->filterBuilderMock = $this->createSimpleMock(FilterBuilder::class); $this->searchCriteriaBuilderMock = $this->createSimpleMock(SearchCriteriaBuilder::class); @@ -160,32 +208,44 @@ protected function setUp() ->getMock(); $allowedCountryReaderMock->method('getAllowedCountries') ->willReturn(['EN'=>'EN']); + $this->dataObjectHelperMock = $this->getMockBuilder(\Magento\Framework\Api\DataObjectHelper::class) + ->disableOriginalConstructor() + ->setMethods(['mergeDataObjects']) + ->getMock(); + $this->placeOrderFactoryMock = $this->getMockBuilder(PlaceOrderFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $logger = $this->createSimpleMock(\Psr\Log\LoggerInterface::class); $this->model = new Multishipping( $this->checkoutSessionMock, $this->customerSessionMock, - $orderFactoryMock, + $this->orderFactoryMock, $this->addressRepositoryMock, $eventManagerMock, $scopeConfigMock, - $sessionMock, + $this->sessionMock, $addressFactoryMock, - $toOrderMock, - $toOrderAddressMock, - $toOrderPaymentMock, - $toOrderItemMock, + $this->toOrderMock, + $this->toOrderAddressMock, + $this->toOrderPaymentMock, + $this->toOrderItemMock, $storeManagerMock, $paymentSpecMock, $this->helperMock, $orderSenderMock, - $priceMock, + $this->priceMock, $this->quoteRepositoryMock, $this->searchCriteriaBuilderMock, $this->filterBuilderMock, $this->totalsCollectorMock, $data, $this->cartExtensionFactoryMock, - $allowedCountryReaderMock + $allowedCountryReaderMock, + $this->placeOrderFactoryMock, + $logger, + $this->dataObjectHelperMock ); $this->shippingAssignmentProcessorMock = $this->createSimpleMock(ShippingAssignmentProcessor::class); @@ -365,6 +425,255 @@ public function testSetShippingMethods() $this->model->setShippingMethods($methodsArray); } + /** + * @return void + */ + public function testCreateOrders(): void + { + $addressTotal = 5; + $productType = \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE; + $infoBuyRequest = [ + 'info_buyRequest' => [ + 'product' => '1', + 'qty' => 1, + ], + ]; + $quoteItemId = 1; + $paymentProviderCode = 'checkmo'; + + $simpleProductTypeMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Type\Simple::class) + ->disableOriginalConstructor() + ->setMethods(['getOrderOptions']) + ->getMock(); + $productMock = $this->getProductMock($simpleProductTypeMock); + $simpleProductTypeMock->method('getOrderOptions')->with($productMock)->willReturn($infoBuyRequest); + + $quoteItemMock = $this->getQuoteItemMock($productType, $productMock); + $quoteAddressItemMock = $this->getQuoteAddressItemMock($quoteItemMock, $productType, $infoBuyRequest); + list($shippingAddressMock, $billingAddressMock) = + $this->getQuoteAddressesMock($quoteAddressItemMock, $addressTotal); + $this->setQuoteMockData($paymentProviderCode, $shippingAddressMock, $billingAddressMock); + + $orderAddressMock = $this->createSimpleMock(\Magento\Sales\Api\Data\OrderAddressInterface::class); + $orderPaymentMock = $this->createSimpleMock(\Magento\Sales\Api\Data\OrderPaymentInterface::class); + $orderItemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class) + ->disableOriginalConstructor() + ->setMethods(['getQuoteItemId']) + ->getMock(); + $orderItemMock->method('getQuoteItemId')->willReturn($quoteItemId); + $orderMock = $this->getOrderMock($orderAddressMock, $orderPaymentMock, $orderItemMock); + + $this->orderFactoryMock->expects($this->once())->method('create')->willReturn($orderMock); + $this->dataObjectHelperMock->expects($this->once())->method('mergeDataObjects') + ->with( + \Magento\Sales\Api\Data\OrderInterface::class, + $orderMock, + $orderMock + )->willReturnSelf(); + $this->priceMock->expects($this->once())->method('round')->with($addressTotal)->willReturn($addressTotal); + + $this->toOrderMock + ->expects($this->once()) + ->method('convert') + ->with($shippingAddressMock) + ->willReturn($orderMock); + $this->toOrderAddressMock->expects($this->exactly(2))->method('convert') + ->withConsecutive( + [$billingAddressMock, []], + [$shippingAddressMock, []] + )->willReturn($orderAddressMock); + $this->toOrderPaymentMock->method('convert')->willReturn($orderPaymentMock); + $this->toOrderItemMock->method('convert')->with($quoteAddressItemMock)->willReturn($orderItemMock); + + $placeOrderServiceMock = $this->getMockBuilder(PlaceOrderDefault::class) + ->disableOriginalConstructor() + ->setMethods(['place']) + ->getMock(); + $placeOrderServiceMock->method('place')->with([$orderMock])->willReturn([]); + $this->placeOrderFactoryMock->method('create')->with($paymentProviderCode)->willReturn($placeOrderServiceMock); + $this->quoteRepositoryMock->method('save')->with($this->quoteMock); + + $this->model->createOrders(); + } + + /** + * @param string $paymentProviderCode + * @return PHPUnit_Framework_MockObject_MockObject + */ + private function getPaymentMock(string $paymentProviderCode): PHPUnit_Framework_MockObject_MockObject + { + $abstractMethod = $this->getMockBuilder(AbstractMethod::class) + ->disableOriginalConstructor() + ->setMethods(['isAvailable']) + ->getMockForAbstractClass(); + $abstractMethod->method('isAvailable')->willReturn(true); + + $paymentMock = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->setMethods(['getMethodInstance', 'getMethod']) + ->getMock(); + $paymentMock->method('getMethodInstance')->willReturn($abstractMethod); + $paymentMock->method('getMethod')->willReturn($paymentProviderCode); + + return $paymentMock; + } + + /** + * @param \Magento\Catalog\Model\Product\Type\Simple|PHPUnit_Framework_MockObject_MockObject $simpleProductTypeMock + * @return PHPUnit_Framework_MockObject_MockObject + */ + private function getProductMock($simpleProductTypeMock): PHPUnit_Framework_MockObject_MockObject + { + $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->disableOriginalConstructor() + ->setMethods(['getTypeInstance']) + ->getMock(); + $productMock->method('getTypeInstance')->willReturn($simpleProductTypeMock); + + return $productMock; + } + + /** + * @param string $productType + * @param \Magento\Catalog\Model\Product|PHPUnit_Framework_MockObject_MockObject $productMock + * @return PHPUnit_Framework_MockObject_MockObject + */ + private function getQuoteItemMock($productType, $productMock): PHPUnit_Framework_MockObject_MockObject + { + $quoteItemMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item::class) + ->disableOriginalConstructor() + ->setMethods(['getProductType', 'getProduct']) + ->getMock(); + $quoteItemMock->method('getProductType')->willReturn($productType); + $quoteItemMock->method('getProduct')->willReturn($productMock); + + return $quoteItemMock; + } + + /** + * @param \Magento\Quote\Model\Quote\Item|PHPUnit_Framework_MockObject_MockObject $quoteItemMock + * @param string $productType + * @param array $infoBuyRequest + * @return PHPUnit_Framework_MockObject_MockObject + */ + private function getQuoteAddressItemMock( + $quoteItemMock, + string $productType, + array $infoBuyRequest + ): PHPUnit_Framework_MockObject_MockObject { + $quoteAddressItemMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Address\Item::class) + ->disableOriginalConstructor() + ->setMethods(['getQuoteItem', 'setProductType', 'setProductOptions', 'getParentItem']) + ->getMock(); + $quoteAddressItemMock->method('getQuoteItem')->willReturn($quoteItemMock); + $quoteAddressItemMock->method('setProductType')->with($productType)->willReturnSelf(); + $quoteAddressItemMock->method('setProductOptions')->willReturn($infoBuyRequest); + $quoteAddressItemMock->method('getParentItem')->willReturn(false); + + return $quoteAddressItemMock; + } + + /** + * @param \Magento\Quote\Model\Quote\Address\Item|PHPUnit_Framework_MockObject_MockObject $quoteAddressItemMock + * @param int $addressTotal + * @return array + */ + private function getQuoteAddressesMock($quoteAddressItemMock, int $addressTotal): array + { + $shippingAddressMock = $this->getMockBuilder(Address::class) + ->disableOriginalConstructor() + ->setMethods( + [ + 'validate', + 'getShippingMethod', + 'getShippingRateByCode', + 'getCountryId', + 'getAddressType', + 'getGrandTotal', + 'getAllItems', + ] + )->getMock(); + $shippingAddressMock->method('validate')->willReturn(true); + $shippingAddressMock->method('getShippingMethod')->willReturn('carrier'); + $shippingAddressMock->method('getShippingRateByCode')->willReturn('code'); + $shippingAddressMock->method('getCountryId')->willReturn('EN'); + $shippingAddressMock->method('getAllItems')->willReturn([$quoteAddressItemMock]); + $shippingAddressMock->method('getAddressType')->willReturn('shipping'); + $shippingAddressMock->method('getGrandTotal')->willReturn($addressTotal); + + $billingAddressMock = $this->getMockBuilder(Address::class) + ->disableOriginalConstructor() + ->setMethods(['validate']) + ->getMock(); + $billingAddressMock->method('validate')->willReturn(true); + + return [$shippingAddressMock, $billingAddressMock]; + } + + /** + * @param string $paymentProviderCode + * @param Address|PHPUnit_Framework_MockObject_MockObject $shippingAddressMock + * @param Address|PHPUnit_Framework_MockObject_MockObject $billingAddressMock + * + * @return void + */ + private function setQuoteMockData(string $paymentProviderCode, $shippingAddressMock, $billingAddressMock): void + { + $quoteId = 1; + $paymentMock = $this->getPaymentMock($paymentProviderCode); + $this->quoteMock->method('getPayment') + ->willReturn($paymentMock); + $this->quoteMock->method('getAllShippingAddresses') + ->willReturn([$shippingAddressMock]); + $this->quoteMock->method('getBillingAddress') + ->willReturn($billingAddressMock); + $this->quoteMock->method('hasVirtualItems') + ->willReturn(false); + $this->quoteMock->expects($this->once())->method('reserveOrderId')->willReturnSelf(); + $this->quoteMock->expects($this->once())->method('collectTotals')->willReturnSelf(); + $this->quoteMock->method('getId')->willReturn($quoteId); + $this->quoteMock->method('setIsActive')->with(false)->willReturnSelf(); + } + + /** + * @param \Magento\Sales\Api\Data\OrderAddressInterface|PHPUnit_Framework_MockObject_MockObject $orderAddressMock + * @param \Magento\Sales\Api\Data\OrderPaymentInterface|PHPUnit_Framework_MockObject_MockObject $orderPaymentMock + * @param \Magento\Sales\Model\Order\Item|PHPUnit_Framework_MockObject_MockObject $orderItemMock + * @return PHPUnit_Framework_MockObject_MockObject + */ + private function getOrderMock( + $orderAddressMock, + $orderPaymentMock, + $orderItemMock + ): PHPUnit_Framework_MockObject_MockObject { + $orderMock = $this->getMockBuilder(\Magento\Sales\Model\Order::class) + ->disableOriginalConstructor() + ->setMethods( + [ + 'setQuote', + 'setBillingAddress', + 'setShippingAddress', + 'setPayment', + 'addItem', + 'getIncrementId', + 'getId', + 'getCanSendNewEmailFlag', + 'getItems', + ] + )->getMock(); + $orderMock->method('setQuote')->with($this->quoteMock); + $orderMock->method('setBillingAddress')->with($orderAddressMock)->willReturnSelf(); + $orderMock->method('setShippingAddress')->with($orderAddressMock)->willReturnSelf(); + $orderMock->method('setPayment')->with($orderPaymentMock)->willReturnSelf(); + $orderMock->method('addItem')->with($orderItemMock)->willReturnSelf(); + $orderMock->method('getIncrementId')->willReturn('1'); + $orderMock->method('getId')->willReturn('1'); + $orderMock->method('getCanSendNewEmailFlag')->willReturn(false); + $orderMock->method('getItems')->willReturn([$orderItemMock]); + + return $orderMock; + } + /** * Tests exception for addresses with country id not in the allowed countries list. * diff --git a/app/code/Magento/MysqlMq/etc/db_schema.xml b/app/code/Magento/MysqlMq/etc/db_schema.xml index 9ef1fc15f1fb5..02757afa53fcd 100644 --- a/app/code/Magento/MysqlMq/etc/db_schema.xml +++ b/app/code/Magento/MysqlMq/etc/db_schema.xml @@ -44,10 +44,10 @@ - - diff --git a/app/code/Magento/MysqlMq/etc/db_schema_whitelist.json b/app/code/Magento/MysqlMq/etc/db_schema_whitelist.json index 9d224cd8cb724..4d5a919320fe9 100644 --- a/app/code/Magento/MysqlMq/etc/db_schema_whitelist.json +++ b/app/code/Magento/MysqlMq/etc/db_schema_whitelist.json @@ -33,9 +33,11 @@ }, "constraint": { "PRIMARY": true, + "QUEUE_MESSAGE_STATUS_MESSAGE_ID_QUEUE_MESSAGE_ID": true, "QUEUE_MESSAGE_ID_QUEUE_MESSAGE_STATUS_MESSAGE_ID": true, + "QUEUE_MESSAGE_STATUS_QUEUE_ID_QUEUE_ID": true, "QUEUE_ID_QUEUE_MESSAGE_STATUS_QUEUE_ID": true, "QUEUE_MESSAGE_STATUS_QUEUE_ID_MESSAGE_ID": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/Newsletter/Controller/Subscriber/Confirm.php b/app/code/Magento/Newsletter/Controller/Subscriber/Confirm.php index 004677b899cd0..4e338c2d1df34 100644 --- a/app/code/Magento/Newsletter/Controller/Subscriber/Confirm.php +++ b/app/code/Magento/Newsletter/Controller/Subscriber/Confirm.php @@ -32,6 +32,8 @@ public function execute() } } - $this->getResponse()->setRedirect($this->_storeManager->getStore()->getBaseUrl()); + $resultRedirect = $this->resultRedirectFactory->create(); + $resultRedirect->setUrl($this->_storeManager->getStore()->getBaseUrl()); + return $resultRedirect; } } diff --git a/app/code/Magento/Newsletter/etc/db_schema_whitelist.json b/app/code/Magento/Newsletter/etc/db_schema_whitelist.json index 237c675f5fcca..27a42a55a174c 100644 --- a/app/code/Magento/Newsletter/etc/db_schema_whitelist.json +++ b/app/code/Magento/Newsletter/etc/db_schema_whitelist.json @@ -11,7 +11,8 @@ }, "index": { "NEWSLETTER_SUBSCRIBER_CUSTOMER_ID": true, - "NEWSLETTER_SUBSCRIBER_STORE_ID": true + "NEWSLETTER_SUBSCRIBER_STORE_ID": true, + "NEWSLETTER_SUBSCRIBER_SUBSCRIBER_EMAIL": true }, "constraint": { "PRIMARY": true, @@ -112,4 +113,4 @@ "NLTTR_PROBLEM_SUBSCRIBER_ID_NLTTR_SUBSCRIBER_SUBSCRIBER_ID": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/Paypal/Model/Ipn.php b/app/code/Magento/Paypal/Model/Ipn.php index a370bbc77ffb2..9107762c54b69 100644 --- a/app/code/Magento/Paypal/Model/Ipn.php +++ b/app/code/Magento/Paypal/Model/Ipn.php @@ -7,9 +7,9 @@ namespace Magento\Paypal\Model; use Exception; +use Magento\Framework\Exception\LocalizedException; use Magento\Sales\Model\Order\Email\Sender\CreditmemoSender; use Magento\Sales\Model\Order\Email\Sender\OrderSender; -use Magento\Paypal\Model\Info; /** * PayPal Instant Payment Notification processor model @@ -164,11 +164,11 @@ protected function _processOrder() case Info::TXN_TYPE_NEW_CASE: $this->_registerDispute(); break; - // handle new adjustment is created + // handle new adjustment is created case Info::TXN_TYPE_ADJUSTMENT: $this->_registerAdjustment(); break; - //handle new transaction created + //handle new transaction created default: $this->_registerTransaction(); break; @@ -239,16 +239,16 @@ protected function _registerTransaction() case Info::PAYMENTSTATUS_COMPLETED: $this->_registerPaymentCapture(true); break; - // the holded payment was denied on paypal side + // the holded payment was denied on paypal side case Info::PAYMENTSTATUS_DENIED: $this->_registerPaymentDenial(); break; - // customer attempted to pay via bank account, but failed + // customer attempted to pay via bank account, but failed case Info::PAYMENTSTATUS_FAILED: // cancel order $this->_registerPaymentFailure(); break; - // payment was obtained, but money were not captured yet + // payment was obtained, but money were not captured yet case Info::PAYMENTSTATUS_PENDING: $this->_registerPaymentPending(); break; @@ -263,7 +263,7 @@ protected function _registerTransaction() case Info::PAYMENTSTATUS_REFUNDED: $this->_registerPaymentRefund(); break; - // authorization expire/void + // authorization expire/void case Info::PAYMENTSTATUS_EXPIRED: // break is intentionally omitted case Info::PAYMENTSTATUS_VOIDED: @@ -288,24 +288,12 @@ protected function _registerPaymentCapture($skipFraudDetection = false) $parentTransactionId = $this->getRequestData('parent_txn_id'); $this->_importPaymentInformation(); $payment = $this->_order->getPayment(); - $payment->setTransactionId( - $this->getRequestData('txn_id') - ); - $payment->setCurrencyCode( - $this->getRequestData('mc_currency') - ); - $payment->setPreparedMessage( - $this->_createIpnComment('') - ); - $payment->setParentTransactionId( - $parentTransactionId - ); - $payment->setShouldCloseParentTransaction( - 'Completed' === $this->getRequestData('auth_status') - ); - $payment->setIsTransactionClosed( - 0 - ); + $payment->setTransactionId($this->getRequestData('txn_id')); + $payment->setCurrencyCode($this->getRequestData('mc_currency')); + $payment->setPreparedMessage($this->_createIpnComment('')); + $payment->setParentTransactionId($parentTransactionId); + $payment->setShouldCloseParentTransaction('Completed' === $this->getRequestData('auth_status')); + $payment->setIsTransactionClosed(0); $payment->registerCaptureNotification( $this->getRequestData('mc_gross'), $skipFraudDetection && $parentTransactionId @@ -318,9 +306,9 @@ protected function _registerPaymentCapture($skipFraudDetection = false) $this->orderSender->send($this->_order); $this->_order->addStatusHistoryComment( __('You notified customer about invoice #%1.', $invoice->getIncrementId()) - )->setIsCustomerNotified( - true - )->save(); + ) + ->setIsCustomerNotified(true) + ->save(); } } @@ -334,15 +322,13 @@ protected function _registerPaymentDenial() { try { $this->_importPaymentInformation(); - $this->_order->getPayment()->setTransactionId( - $this->getRequestData('txn_id') - )->setNotificationResult( - true - )->setIsTransactionClosed( - true - )->deny(false); + $this->_order->getPayment() + ->setTransactionId($this->getRequestData('txn_id')) + ->setNotificationResult(true) + ->setIsTransactionClosed(true) + ->deny(false); $this->_order->save(); - } catch (\Magento\Framework\Exception\LocalizedException $e) { + } catch (LocalizedException $e) { if ($e->getMessage() != __('We cannot cancel this order.')) { throw $e; } @@ -386,13 +372,11 @@ public function _registerPaymentPending() $this->_importPaymentInformation(); - $this->_order->getPayment()->setPreparedMessage( - $this->_createIpnComment($this->_paypalInfo->explainPendingReason($reason)) - )->setTransactionId( - $this->getRequestData('txn_id') - )->setIsTransactionClosed( - 0 - )->update(false); + $this->_order->getPayment() + ->setPreparedMessage($this->_createIpnComment($this->_paypalInfo->explainPendingReason($reason))) + ->setTransactionId($this->getRequestData('txn_id')) + ->setIsTransactionClosed(0) + ->update(false); $this->_order->save(); } @@ -409,19 +393,12 @@ protected function _registerPaymentAuthorization() $payment->update(true); } else { $this->_importPaymentInformation(); - $payment->setPreparedMessage( - $this->_createIpnComment('') - )->setTransactionId( - $this->getRequestData('txn_id') - )->setParentTransactionId( - $this->getRequestData('parent_txn_id') - )->setCurrencyCode( - $this->getRequestData('mc_currency') - )->setIsTransactionClosed( - 0 - )->registerAuthorizationNotification( - $this->getRequestData('mc_gross') - ); + $payment->setPreparedMessage($this->_createIpnComment('')) + ->setTransactionId($this->getRequestData('txn_id')) + ->setParentTransactionId($this->getRequestData('parent_txn_id')) + ->setCurrencyCode($this->getRequestData('mc_currency')) + ->setIsTransactionClosed(0) + ->registerAuthorizationNotification($this->getRequestData('mc_gross')); } if (!$this->_order->getEmailSent()) { $this->orderSender->send($this->_order); @@ -449,12 +426,13 @@ protected function _registerPaymentReversal() { $reasonCode = $this->getRequestData('reason_code'); $reasonComment = $this->_paypalInfo->explainReasonCode($reasonCode); - $notificationAmount = $this->_order->getBaseCurrency()->formatTxt( - $this->getRequestData('mc_gross') + $this->getRequestData('mc_fee') - ); + $notificationAmount = $this->_order->getBaseCurrency() + ->formatTxt( + $this->getRequestData('mc_gross') + $this->getRequestData('mc_fee') + ); $paymentStatus = $this->_filterPaymentStatus($this->getRequestData('payment_status')); $orderStatus = $paymentStatus == - Info::PAYMENTSTATUS_REVERSED ? Info::ORDER_STATUS_REVERSED : Info::ORDER_STATUS_CANCELED_REVERSAL; + Info::PAYMENTSTATUS_REVERSED ? Info::ORDER_STATUS_REVERSED : Info::ORDER_STATUS_CANCELED_REVERSAL; //Change order status to PayPal Reversed/PayPal Cancelled Reversal if it is possible. $message = __( 'IPN "%1". %2 Transaction amount %3. Transaction ID: "%4"', @@ -464,8 +442,9 @@ protected function _registerPaymentReversal() $this->getRequestData('txn_id') ); $this->_order->setStatus($orderStatus); - $this->_order->save(); - $this->_order->addStatusHistoryComment($message, $orderStatus)->setIsCustomerNotified(false)->save(); + $this->_order->addStatusHistoryComment($message, $orderStatus) + ->setIsCustomerNotified(false) + ->save(); } /** @@ -478,17 +457,12 @@ protected function _registerPaymentRefund() $this->_importPaymentInformation(); $reason = $this->getRequestData('reason_code'); $isRefundFinal = !$this->_paypalInfo->isReversalDisputable($reason); - $payment = $this->_order->getPayment()->setPreparedMessage( - $this->_createIpnComment($this->_paypalInfo->explainReasonCode($reason)) - )->setTransactionId( - $this->getRequestData('txn_id') - )->setParentTransactionId( - $this->getRequestData('parent_txn_id') - )->setIsTransactionClosed( - $isRefundFinal - )->registerRefundNotification( - -1 * $this->getRequestData('mc_gross') - ); + $payment = $this->_order->getPayment() + ->setPreparedMessage($this->_createIpnComment($this->_paypalInfo->explainReasonCode($reason))) + ->setTransactionId($this->getRequestData('txn_id')) + ->setParentTransactionId($this->getRequestData('parent_txn_id')) + ->setIsTransactionClosed($isRefundFinal) + ->registerRefundNotification(-1 * $this->getRequestData('mc_gross')); $this->_order->save(); // TODO: there is no way to close a capture right now @@ -498,9 +472,9 @@ protected function _registerPaymentRefund() $this->creditmemoSender->send($creditMemo); $this->_order->addStatusHistoryComment( __('You notified customer about creditmemo #%1.', $creditMemo->getIncrementId()) - )->setIsCustomerNotified( - true - )->save(); + ) + ->setIsCustomerNotified(true) + ->save(); } } @@ -513,19 +487,14 @@ protected function _registerPaymentVoid() { $this->_importPaymentInformation(); - $parentTxnId = $this->getRequestData( - 'transaction_entity' - ) == 'auth' ? $this->getRequestData( - 'txn_id' - ) : $this->getRequestData( - 'parent_txn_id' - ); + $parentTxnId = $this->getRequestData('transaction_entity') == 'auth' + ? $this->getRequestData('txn_id') + : $this->getRequestData('parent_txn_id'); - $this->_order->getPayment()->setPreparedMessage( - $this->_createIpnComment('') - )->setParentTransactionId( - $parentTxnId - )->registerVoidNotification(); + $this->_order->getPayment() + ->setPreparedMessage($this->_createIpnComment('')) + ->setParentTransactionId($parentTxnId) + ->registerVoidNotification(); $this->_order->save(); } @@ -546,14 +515,14 @@ protected function _importPaymentInformation() // collect basic information $from = []; foreach ([ - Info::PAYER_ID, - 'payer_email' => Info::PAYER_EMAIL, - Info::PAYER_STATUS, - Info::ADDRESS_STATUS, - Info::PROTECTION_EL, - Info::PAYMENT_STATUS, - Info::PENDING_REASON, - ] as $privateKey => $publicKey) { + Info::PAYER_ID, + 'payer_email' => Info::PAYER_EMAIL, + Info::PAYER_STATUS, + Info::ADDRESS_STATUS, + Info::PROTECTION_EL, + Info::PAYMENT_STATUS, + Info::PENDING_REASON, + ] as $privateKey => $publicKey) { if (is_int($privateKey)) { $privateKey = $publicKey; } diff --git a/app/code/Magento/Paypal/view/frontend/web/order-review.js b/app/code/Magento/Paypal/view/frontend/web/order-review.js index 566c9c8da06dc..2155b52f4081b 100644 --- a/app/code/Magento/Paypal/view/frontend/web/order-review.js +++ b/app/code/Magento/Paypal/view/frontend/web/order-review.js @@ -108,7 +108,7 @@ define([ }, /** - * trigger change for the update of shippping methods from server + * trigger change for the update of shipping methods from server */ _updateOrderHandler: function () { $(this.options.shippingSelector).trigger('change'); @@ -297,7 +297,7 @@ define([ this._updateOrderSubmit(true); this._toggleButton(this.options.updateOrderSelector, true); - // form data and callBack updated based on the shippping Form element + // form data and callBack updated based on the shipping Form element if (this.isShippingSubmitForm) { formData = $(this.options.shippingSubmitFormSelector).serialize() + '&isAjax=true'; diff --git a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php index 2aaf0f30fe71d..f3720960ca6e5 100644 --- a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php +++ b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php @@ -50,6 +50,20 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface */ protected $_persistentData = null; + /** + * Request + * + * @var \Magento\Framework\App\RequestInterface + */ + private $request; + + /** + * Checkout Page path + * + * @var string + */ + private $checkoutPagePath = 'checkout'; + /** * @param \Magento\Persistent\Helper\Session $persistentSession * @param \Magento\Persistent\Helper\Data $persistentData @@ -57,6 +71,7 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Checkout\Model\Session $checkoutSession + * @param \Magento\Framework\App\RequestInterface $request */ public function __construct( \Magento\Persistent\Helper\Session $persistentSession, @@ -64,7 +79,8 @@ public function __construct( \Magento\Persistent\Model\QuoteManager $quoteManager, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Customer\Model\Session $customerSession, - \Magento\Checkout\Model\Session $checkoutSession + \Magento\Checkout\Model\Session $checkoutSession, + \Magento\Framework\App\RequestInterface $request ) { $this->_persistentSession = $persistentSession; $this->quoteManager = $quoteManager; @@ -72,6 +88,7 @@ public function __construct( $this->_checkoutSession = $checkoutSession; $this->_eventManager = $eventManager; $this->_persistentData = $persistentData; + $this->request = $request; } /** @@ -90,12 +107,32 @@ public function execute(\Magento\Framework\Event\Observer $observer) !$this->_persistentSession->isPersistent() && !$this->_customerSession->isLoggedIn() && $this->_checkoutSession->getQuoteId() && - !$observer->getControllerAction() instanceof \Magento\Checkout\Controller\Onepage - // persistent session does not expire on onepage checkout page to not spoil customer group id + !$this->isRequestFromCheckoutPage($this->request) + // persistent session does not expire on onepage checkout page ) { $this->_eventManager->dispatch('persistent_session_expired'); $this->quoteManager->expire(); $this->_customerSession->setCustomerId(null)->setCustomerGroupId(null); } } + + /** + * Check current request is coming from onepage checkout page. + * + * @param \Magento\Framework\App\RequestInterface $request + * @return bool + */ + private function isRequestFromCheckoutPage(\Magento\Framework\App\RequestInterface $request): bool + { + $requestUri = (string)$request->getRequestUri(); + $refererUri = (string)$request->getServer('HTTP_REFERER'); + + /** @var bool $isCheckoutPage */ + $isCheckoutPage = ( + false !== strpos($requestUri, $this->checkoutPagePath) || + false !== strpos($refererUri, $this->checkoutPagePath) + ); + + return $isCheckoutPage; + } } diff --git a/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php b/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php index a52e22a960e0b..8cad0b9f2dd89 100644 --- a/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php @@ -49,24 +49,39 @@ class CheckExpirePersistentQuoteObserverTest extends \PHPUnit\Framework\TestCase */ protected $eventManagerMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\RequestInterface + */ + private $requestMock; + + /** + * @inheritdoc + */ protected function setUp() { $this->sessionMock = $this->createMock(\Magento\Persistent\Helper\Session::class); $this->customerSessionMock = $this->createMock(\Magento\Customer\Model\Session::class); $this->persistentHelperMock = $this->createMock(\Magento\Persistent\Helper\Data::class); - $this->observerMock - = $this->createPartialMock(\Magento\Framework\Event\Observer::class, ['getControllerAction', - '__wakeUp']); + $this->observerMock = $this->createPartialMock( + \Magento\Framework\Event\Observer::class, + ['getControllerAction','__wakeUp'] + ); $this->quoteManagerMock = $this->createMock(\Magento\Persistent\Model\QuoteManager::class); $this->eventManagerMock = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); $this->checkoutSessionMock = $this->createMock(\Magento\Checkout\Model\Session::class); + $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getRequestUri', 'getServer']) + ->getMockForAbstractClass(); + $this->model = new \Magento\Persistent\Observer\CheckExpirePersistentQuoteObserver( $this->sessionMock, $this->persistentHelperMock, $this->quoteManagerMock, $this->eventManagerMock, $this->customerSessionMock, - $this->checkoutSessionMock + $this->checkoutSessionMock, + $this->requestMock ); } @@ -76,7 +91,7 @@ public function testExecuteWhenCanNotApplyPersistentData() ->expects($this->once()) ->method('canProcess') ->with($this->observerMock) - ->will($this->returnValue(false)); + ->willReturn(false); $this->persistentHelperMock->expects($this->never())->method('isEnabled'); $this->model->execute($this->observerMock); } @@ -87,31 +102,97 @@ public function testExecuteWhenPersistentIsNotEnabled() ->expects($this->once()) ->method('canProcess') ->with($this->observerMock) - ->will($this->returnValue(true)); - $this->persistentHelperMock->expects($this->once())->method('isEnabled')->will($this->returnValue(false)); + ->willReturn(true); + $this->persistentHelperMock->expects($this->once())->method('isEnabled')->willReturn(false); $this->eventManagerMock->expects($this->never())->method('dispatch'); $this->model->execute($this->observerMock); } - public function testExecuteWhenPersistentIsEnabled() - { + /** + * Test method \Magento\Persistent\Observer\CheckExpirePersistentQuoteObserver::execute when persistent is enabled. + * + * @param string $refererUri + * @param string $requestUri + * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $expireCounter + * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $dispatchCounter + * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $setCustomerIdCounter + * @return void + * @dataProvider requestDataProvider + */ + public function testExecuteWhenPersistentIsEnabled( + string $refererUri, + string $requestUri, + \PHPUnit_Framework_MockObject_Matcher_InvokedCount $expireCounter, + \PHPUnit_Framework_MockObject_Matcher_InvokedCount $dispatchCounter, + \PHPUnit_Framework_MockObject_Matcher_InvokedCount $setCustomerIdCounter + ): void { $this->persistentHelperMock ->expects($this->once()) ->method('canProcess') ->with($this->observerMock) - ->will($this->returnValue(true)); - $this->persistentHelperMock->expects($this->once())->method('isEnabled')->will($this->returnValue(true)); - $this->sessionMock->expects($this->once())->method('isPersistent')->will($this->returnValue(false)); - $this->customerSessionMock->expects($this->once())->method('isLoggedIn')->will($this->returnValue(false)); - $this->checkoutSessionMock->expects($this->once())->method('getQuoteId')->will($this->returnValue(10)); - $this->observerMock->expects($this->once())->method('getControllerAction'); - $this->eventManagerMock->expects($this->once())->method('dispatch'); - $this->quoteManagerMock->expects($this->once())->method('expire'); + ->willReturn(true); + $this->persistentHelperMock->expects($this->once())->method('isEnabled')->willReturn(true); + $this->sessionMock->expects($this->once())->method('isPersistent')->willReturn(false); $this->customerSessionMock - ->expects($this->once()) + ->expects($this->atLeastOnce()) + ->method('isLoggedIn') + ->willReturn(false); + $this->checkoutSessionMock + ->expects($this->atLeastOnce()) + ->method('getQuoteId') + ->willReturn(10); + $this->eventManagerMock->expects($dispatchCounter)->method('dispatch'); + $this->quoteManagerMock->expects($expireCounter)->method('expire'); + $this->customerSessionMock + ->expects($setCustomerIdCounter) ->method('setCustomerId') ->with(null) - ->will($this->returnSelf()); + ->willReturnSelf(); + $this->requestMock->expects($this->atLeastOnce())->method('getRequestUri')->willReturn($refererUri); + $this->requestMock + ->expects($this->atLeastOnce()) + ->method('getServer') + ->with('HTTP_REFERER') + ->willReturn($requestUri); $this->model->execute($this->observerMock); } + + /** + * Request Data Provider + * + * @return array + */ + public function requestDataProvider() + { + return [ + [ + 'refererUri' => 'checkout', + 'requestUri' => 'index', + 'expireCounter' => $this->never(), + 'dispatchCounter' => $this->never(), + 'setCustomerIdCounter' => $this->never(), + ], + [ + 'refererUri' => 'checkout', + 'requestUri' => 'checkout', + 'expireCounter' => $this->never(), + 'dispatchCounter' => $this->never(), + 'setCustomerIdCounter' => $this->never(), + ], + [ + 'refererUri' => 'index', + 'requestUri' => 'checkout', + 'expireCounter' => $this->never(), + 'dispatchCounter' => $this->never(), + 'setCustomerIdCounter' => $this->never(), + ], + [ + 'refererUri' => 'index', + 'requestUri' => 'index', + 'expireCounter' => $this->once(), + 'dispatchCounter' => $this->once(), + 'setCustomerIdCounter' => $this->once(), + ], + ]; + } } diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php index ad90b75cbb0d5..3b19c6495dd99 100644 --- a/app/code/Magento/Quote/Model/Quote.php +++ b/app/code/Magento/Quote/Model/Quote.php @@ -2021,7 +2021,7 @@ public function getErrors() foreach ($this->getMessages() as $message) { /* @var $error \Magento\Framework\Message\AbstractMessage */ if ($message->getType() == \Magento\Framework\Message\MessageInterface::TYPE_ERROR) { - array_push($errors, $message); + $errors[] = $message; } } return $errors; diff --git a/app/code/Magento/Rule/Model/Action/AbstractAction.php b/app/code/Magento/Rule/Model/Action/AbstractAction.php index fb15edf8a4893..4d56f6cc56edc 100644 --- a/app/code/Magento/Rule/Model/Action/AbstractAction.php +++ b/app/code/Magento/Rule/Model/Action/AbstractAction.php @@ -49,13 +49,16 @@ public function __construct( $this->loadAttributeOptions()->loadOperatorOptions()->loadValueOptions(); - foreach (array_keys($this->getAttributeOption()) as $attr) { - $this->setAttribute($attr); - break; + $attributes = $this->getAttributeOption(); + if ($attributes) { + reset($attributes); + $this->setAttribute(key($attributes)); } - foreach (array_keys($this->getOperatorOption()) as $operator) { - $this->setOperator($operator); - break; + + $operators = $this->getOperatorOption(); + if ($operators) { + reset($operators); + $this->setOperator(key($operators)); } } diff --git a/app/code/Magento/Rule/Model/Condition/Combine.php b/app/code/Magento/Rule/Model/Condition/Combine.php index 24ed1cb497472..48873aec66295 100644 --- a/app/code/Magento/Rule/Model/Condition/Combine.php +++ b/app/code/Magento/Rule/Model/Condition/Combine.php @@ -46,10 +46,8 @@ public function __construct(Context $context, array $data = []) $this->loadAggregatorOptions(); $options = $this->getAggregatorOptions(); if ($options) { - foreach (array_keys($options) as $aggregator) { - $this->setAggregator($aggregator); - break; - } + reset($options); + $this->setAggregator(key($options)); } } @@ -90,9 +88,10 @@ public function getAggregatorName() public function getAggregatorElement() { if ($this->getAggregator() === null) { - foreach (array_keys($this->getAggregatorOption()) as $key) { - $this->setAggregator($key); - break; + $options = $this->getAggregatorOption(); + if ($options) { + reset($options); + $this->setAggregator(key($options)); } } return $this->getForm()->addField( diff --git a/app/code/Magento/Rule/view/adminhtml/web/conditions-data-normalizer.js b/app/code/Magento/Rule/view/adminhtml/web/conditions-data-normalizer.js index c9c36c4fa585a..8eebc9ef0bd40 100644 --- a/app/code/Magento/Rule/view/adminhtml/web/conditions-data-normalizer.js +++ b/app/code/Magento/Rule/view/adminhtml/web/conditions-data-normalizer.js @@ -14,11 +14,11 @@ define([ */ var ConditionsDataNormalizer = function () { this.patterns = { - validate: /^[a-z0-9_-][a-z0-9_-]*(?:\[(?:\d*|[a-z0-9_-]+)\])*$/i, - key: /[a-z0-9_-]+|(?=\[\])/gi, + validate: /^[a-z0-9_.-][a-z0-9_.-]*(?:\[(?:\d*|[a-z0-9_.-]+)\])*$/i, + key: /[a-z0-9_.-]+|(?=\[\])/gi, push: /^$/, fixed: /^\d+$/, - named: /^[a-z0-9_-]+$/i + named: /^[a-z0-9_.-]+$/i }; }; diff --git a/app/code/Magento/Sales/Model/EmailSenderHandler.php b/app/code/Magento/Sales/Model/EmailSenderHandler.php index 73d4eacdd1fc8..fe8f1685fe525 100644 --- a/app/code/Magento/Sales/Model/EmailSenderHandler.php +++ b/app/code/Magento/Sales/Model/EmailSenderHandler.php @@ -5,6 +5,8 @@ */ namespace Magento\Sales\Model; +use Magento\Sales\Model\Order\Email\Container\IdentityInterface; + /** * Sales emails sending * @@ -41,22 +43,42 @@ class EmailSenderHandler */ protected $globalConfig; + /** + * @var IdentityInterface + */ + private $identityContainer; + + /** + * @var \Magento\Store\Model\StoreManagerInterface + */ + private $storeManager; + /** * @param \Magento\Sales\Model\Order\Email\Sender $emailSender * @param \Magento\Sales\Model\ResourceModel\EntityAbstract $entityResource * @param \Magento\Sales\Model\ResourceModel\Collection\AbstractCollection $entityCollection * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig + * @param IdentityInterface|null $identityContainer + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @throws \InvalidArgumentException */ public function __construct( \Magento\Sales\Model\Order\Email\Sender $emailSender, \Magento\Sales\Model\ResourceModel\EntityAbstract $entityResource, \Magento\Sales\Model\ResourceModel\Collection\AbstractCollection $entityCollection, - \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig + \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig, + IdentityInterface $identityContainer = null, + \Magento\Store\Model\StoreManagerInterface $storeManager = null ) { $this->emailSender = $emailSender; $this->entityResource = $entityResource; $this->entityCollection = $entityCollection; $this->globalConfig = $globalConfig; + + $this->identityContainer = $identityContainer ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Sales\Model\Order\Email\Container\NullIdentity::class); + $this->storeManager = $storeManager ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Store\Model\StoreManagerInterface::class); } /** @@ -69,14 +91,50 @@ public function sendEmails() $this->entityCollection->addFieldToFilter('send_email', ['eq' => 1]); $this->entityCollection->addFieldToFilter('email_sent', ['null' => true]); - /** @var \Magento\Sales\Model\AbstractModel $item */ - foreach ($this->entityCollection->getItems() as $item) { - if ($this->emailSender->send($item, true)) { - $this->entityResource->save( - $item->setEmailSent(true) - ); + /** @var \Magento\Store\Api\Data\StoreInterface[] $stores */ + $stores = $this->getStores(clone $this->entityCollection); + + /** @var \Magento\Store\Model\Store $store */ + foreach ($stores as $store) { + $this->identityContainer->setStore($store); + if (!$this->identityContainer->isEnabled()) { + continue; + } + $entityCollection = clone $this->entityCollection; + $entityCollection->addFieldToFilter('store_id', $store->getId()); + + /** @var \Magento\Sales\Model\AbstractModel $item */ + foreach ($entityCollection->getItems() as $item) { + if ($this->emailSender->send($item, true)) { + $this->entityResource->save( + $item->setEmailSent(true) + ); + } } } } } + + /** + * Get stores for given entities. + * + * @param ResourceModel\Collection\AbstractCollection $entityCollection + * @return \Magento\Store\Api\Data\StoreInterface[] + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + private function getStores( + \Magento\Sales\Model\ResourceModel\Collection\AbstractCollection $entityCollection + ): array { + $stores = []; + + $entityCollection->addAttributeToSelect('store_id')->getSelect()->group('store_id'); + /** @var \Magento\Sales\Model\EntityInterface $item */ + foreach ($entityCollection->getItems() as $item) { + /** @var \Magento\Store\Model\StoreManagerInterface $store */ + $store = $this->storeManager->getStore($item->getStoreId()); + $stores[$item->getStoreId()] = $store; + } + + return $stores; + } } diff --git a/app/code/Magento/Sales/Model/Order/Email/Container/IdentityInterface.php b/app/code/Magento/Sales/Model/Order/Email/Container/IdentityInterface.php index 55ce24e23e1ec..1d481a8acee65 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Container/IdentityInterface.php +++ b/app/code/Magento/Sales/Model/Order/Email/Container/IdentityInterface.php @@ -3,7 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Sales\Model\Order\Email\Container; + +namespace Magento\Sales\Model\Order\Email\Container; use Magento\Store\Model\Store; diff --git a/app/code/Magento/Sales/Model/Order/Email/Container/NullIdentity.php b/app/code/Magento/Sales/Model/Order/Email/Container/NullIdentity.php new file mode 100644 index 0000000000000..22348aa9ee2f6 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Email/Container/NullIdentity.php @@ -0,0 +1,59 @@ +getState() ?: Order::STATE_PROCESSING; $status = null; $message = 'Registered notification about captured amount of %1.'; diff --git a/app/code/Magento/Sales/Model/ResourceModel/Grid.php b/app/code/Magento/Sales/Model/ResourceModel/Grid.php index b3425baf1e727..42e5d92fb00cc 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Grid.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Grid.php @@ -45,6 +45,11 @@ class Grid extends AbstractGrid */ private $notSyncedDataProvider; + /** + * Order grid rows batch size + */ + const BATCH_SIZE = 100; + /** * @param Context $context * @param string $mainTableName @@ -104,25 +109,20 @@ public function refresh($value, $field = null) * * Only orders created/updated since the last method call will be added. * - * @return \Zend_Db_Statement_Interface + * @return void */ public function refreshBySchedule() { - $select = $this->getGridOriginSelect() - ->where( - $this->mainTableName . '.entity_id IN (?)', - $this->notSyncedDataProvider->getIds($this->mainTableName, $this->gridTableName) + $notSyncedIds = $this->notSyncedDataProvider->getIds($this->mainTableName, $this->gridTableName); + foreach (array_chunk($notSyncedIds, self::BATCH_SIZE) as $bunch) { + $select = $this->getGridOriginSelect()->where($this->mainTableName . '.entity_id IN (?)', $bunch); + $fetchResult = $this->getConnection()->fetchAll($select); + $this->getConnection()->insertOnDuplicate( + $this->getTable($this->gridTableName), + $fetchResult, + array_keys($this->columns) ); - - return $this->getConnection()->query( - $this->getConnection() - ->insertFromSelect( - $select, - $this->getTable($this->gridTableName), - array_keys($this->columns), - AdapterInterface::INSERT_ON_DUPLICATE - ) - ); + } } /** diff --git a/app/code/Magento/Sales/Model/ResourceModel/GridInterface.php b/app/code/Magento/Sales/Model/ResourceModel/GridInterface.php index 9b0e53347e21a..6c7d983f066e5 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/GridInterface.php +++ b/app/code/Magento/Sales/Model/ResourceModel/GridInterface.php @@ -29,7 +29,7 @@ public function refresh($value, $field = null); * * Only rows created/updated since the last method call should be added. * - * @return \Zend_Db_Statement_Interface + * @return void */ public function refreshBySchedule(); diff --git a/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php b/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php index 0ad2245a6287e..d3e13334bb3f9 100644 --- a/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php +++ b/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php @@ -93,27 +93,27 @@ public function apply() public function fillQuoteAddressIdInSalesOrderAddress() { $addressCollection = $this->addressCollectionFactory->create(); + $addressCollection->addFieldToFilter('quote_address_id', ['null' => true]); + /** @var \Magento\Sales\Model\Order\Address $orderAddress */ foreach ($addressCollection as $orderAddress) { - if (!$orderAddress->getData('quote_address_id')) { - $orderId = $orderAddress->getParentId(); - $addressType = $orderAddress->getAddressType(); - - /** @var \Magento\Sales\Model\Order $order */ - $order = $this->orderFactory->create()->load($orderId); - $quoteId = $order->getQuoteId(); - $quote = $this->quoteFactory->create()->load($quoteId); - - if ($addressType == \Magento\Sales\Model\Order\Address::TYPE_SHIPPING) { - $quoteAddressId = $quote->getShippingAddress()->getId(); - $orderAddress->setData('quote_address_id', $quoteAddressId); - } elseif ($addressType == \Magento\Sales\Model\Order\Address::TYPE_BILLING) { - $quoteAddressId = $quote->getBillingAddress()->getId(); - $orderAddress->setData('quote_address_id', $quoteAddressId); - } - - $orderAddress->save(); + $orderId = $orderAddress->getParentId(); + $addressType = $orderAddress->getAddressType(); + + /** @var \Magento\Sales\Model\Order $order */ + $order = $this->orderFactory->create()->load($orderId); + $quoteId = $order->getQuoteId(); + $quote = $this->quoteFactory->create()->load($quoteId); + + if ($addressType == \Magento\Sales\Model\Order\Address::TYPE_SHIPPING) { + $quoteAddressId = $quote->getShippingAddress()->getId(); + $orderAddress->setData('quote_address_id', $quoteAddressId); + } elseif ($addressType == \Magento\Sales\Model\Order\Address::TYPE_BILLING) { + $quoteAddressId = $quote->getBillingAddress()->getId(); + $orderAddress->setData('quote_address_id', $quoteAddressId); } + + $orderAddress->save(); } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/EmailSenderHandlerTest.php b/app/code/Magento/Sales/Test/Unit/Model/EmailSenderHandlerTest.php index 8d3aaa4dae616..56ec763a31cfe 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/EmailSenderHandlerTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/EmailSenderHandlerTest.php @@ -47,6 +47,16 @@ class EmailSenderHandlerTest extends \PHPUnit\Framework\TestCase */ protected $globalConfig; + /** + * @var \Magento\Sales\Model\Order\Email\Container\IdentityInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $identityContainerMock; + + /** + * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeManagerMock; + protected function setUp() { $objectManager = new ObjectManager($this); @@ -70,18 +80,28 @@ protected function setUp() false, false, true, - ['addFieldToFilter', 'getItems'] + ['addFieldToFilter', 'getItems', 'addAttributeToSelect', 'getSelect'] ); $this->globalConfig = $this->createMock(\Magento\Framework\App\Config::class); + $this->identityContainerMock = $this->createMock( + \Magento\Sales\Model\Order\Email\Container\IdentityInterface::class + ); + + $this->storeManagerMock = $this->createMock( + \Magento\Store\Model\StoreManagerInterface::class + ); + $this->object = $objectManager->getObject( \Magento\Sales\Model\EmailSenderHandler::class, [ - 'emailSender' => $this->emailSender, - 'entityResource' => $this->entityResource, - 'entityCollection' => $this->entityCollection, - 'globalConfig' => $this->globalConfig + 'emailSender' => $this->emailSender, + 'entityResource' => $this->entityResource, + 'entityCollection' => $this->entityCollection, + 'globalConfig' => $this->globalConfig, + 'identityContainer' => $this->identityContainerMock, + 'storeManager' => $this->storeManagerMock, ] ); } @@ -114,12 +134,32 @@ public function testExecute($configValue, $collectionItems, $emailSendingResult) ->method('addFieldToFilter') ->with('email_sent', ['null' => true]); + $this->entityCollection + ->expects($this->any()) + ->method('addAttributeToSelect') + ->with('store_id') + ->willReturnSelf(); + + $selectMock = $this->createMock(\Magento\Framework\DB\Select::class); + + $selectMock + ->expects($this->atLeastOnce()) + ->method('group') + ->with('store_id') + ->willReturnSelf(); + + $this->entityCollection + ->expects($this->any()) + ->method('getSelect') + ->willReturn($selectMock); + $this->entityCollection ->expects($this->any()) ->method('getItems') ->willReturn($collectionItems); if ($collectionItems) { + /** @var \Magento\Sales\Model\AbstractModel|\PHPUnit_Framework_MockObject_MockObject $collectionItem */ $collectionItem = $collectionItems[0]; @@ -129,6 +169,23 @@ public function testExecute($configValue, $collectionItems, $emailSendingResult) ->with($collectionItem, true) ->willReturn($emailSendingResult); + $storeMock = $this->createMock(\Magento\Store\Model\Store::class); + + $this->storeManagerMock + ->expects($this->any()) + ->method('getStore') + ->willReturn($storeMock); + + $this->identityContainerMock + ->expects($this->any()) + ->method('setStore') + ->with($storeMock); + + $this->identityContainerMock + ->expects($this->any()) + ->method('isEnabled') + ->willReturn(true); + if ($emailSendingResult) { $collectionItem ->expects($this->once()) @@ -159,14 +216,30 @@ public function executeDataProvider() false, false, true, - ['setEmailSent'] + ['setEmailSent', 'getOrder'] ); return [ - [1, [$entityModel], true], - [1, [$entityModel], false], - [1, [], null], - [0, null, null] + [ + 'configValue' => 1, + 'collectionItems' => [clone $entityModel], + 'emailSendingResult' => true, + ], + [ + 'configValue' => 1, + 'collectionItems' => [clone $entityModel], + 'emailSendingResult' => false, + ], + [ + 'configValue' => 1, + 'collectionItems' => [], + 'emailSendingResult' => null, + ], + [ + 'configValue' => 0, + 'collectionItems' => null, + 'emailSendingResult' => null, + ] ]; } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/State/RegisterCaptureNotificationCommandTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/State/RegisterCaptureNotificationCommandTest.php index 32ea9d8869344..1b762fafe0b71 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/State/RegisterCaptureNotificationCommandTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/State/RegisterCaptureNotificationCommandTest.php @@ -32,26 +32,29 @@ class RegisterCaptureNotificationCommandTest extends \PHPUnit\Framework\TestCase * * @param bool $isTransactionPending * @param bool $isFraudDetected + * @param string|null $currentState * @param string $expectedState * @param string $expectedStatus * @param string $expectedMessage - * + * @return void * @dataProvider commandResultDataProvider */ public function testExecute( - $isTransactionPending, - $isFraudDetected, - $expectedState, - $expectedStatus, - $expectedMessage - ) { + bool $isTransactionPending, + bool $isFraudDetected, + $currentState, + string $expectedState, + string $expectedStatus, + string $expectedMessage + ): void { + $order = $this->getOrder($currentState); $actualReturn = (new RegisterCaptureNotificationCommand($this->getStatusResolver()))->execute( $this->getPayment($isTransactionPending, $isFraudDetected), $this->amount, - $this->getOrder() + $order ); - $this->assertOrderStateAndStatus($this->getOrder(), $expectedState, $expectedStatus); + $this->assertOrderStateAndStatus($order, $expectedState, $expectedStatus); self::assertEquals(__($expectedMessage, $this->amount), $actualReturn); } @@ -64,30 +67,42 @@ public function commandResultDataProvider() [ false, false, + Order::STATE_COMPLETE, + Order::STATE_COMPLETE, + $this->newOrderStatus, + 'Registered notification about captured amount of %1.', + ], + [ + false, + false, + null, Order::STATE_PROCESSING, $this->newOrderStatus, - 'Registered notification about captured amount of %1.' + 'Registered notification about captured amount of %1.', ], [ true, false, + Order::STATE_PROCESSING, Order::STATE_PAYMENT_REVIEW, $this->newOrderStatus, - 'An amount of %1 will be captured after being approved at the payment gateway.' + 'An amount of %1 will be captured after being approved at the payment gateway.', ], [ false, true, + Order::STATE_PROCESSING, Order::STATE_PAYMENT_REVIEW, Order::STATUS_FRAUD, - 'Order is suspended as its capture amount %1 is suspected to be fraudulent.' + 'Order is suspended as its capture amount %1 is suspected to be fraudulent.', ], [ true, true, + Order::STATE_PROCESSING, Order::STATE_PAYMENT_REVIEW, Order::STATUS_FRAUD, - 'Order is suspended as its capture amount %1 is suspected to be fraudulent.' + 'Order is suspended as its capture amount %1 is suspected to be fraudulent.', ], ]; } @@ -107,15 +122,19 @@ private function getStatusResolver() } /** + * @param string|null $state * @return Order|MockObject */ - private function getOrder() + private function getOrder($state) { + /** @var Order|MockObject $order */ $order = $this->getMockBuilder(Order::class) ->disableOriginalConstructor() + ->setMethods(['getBaseCurrency', 'getOrderStatusByState']) ->getMock(); $order->method('getBaseCurrency') ->willReturn($this->getCurrency()); + $order->setState($state); return $order; } @@ -159,7 +178,7 @@ private function getCurrency() */ private function assertOrderStateAndStatus($order, $expectedState, $expectedStatus) { - $order->method('setState')->with($expectedState); - $order->method('setStatus')->with($expectedStatus); + self::assertEquals($expectedState, $order->getState(), 'The order {state} should match.'); + self::assertEquals($expectedStatus, $order->getStatus(), 'The order {status} should match.'); } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/GridTest.php b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/GridTest.php new file mode 100644 index 0000000000000..0c38ee9c509a5 --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/GridTest.php @@ -0,0 +1,109 @@ + 'column_1_value', + 'column_2_key' => 'column_2_value' + ]; + + /** + * @inheritdoc + */ + protected function setUp() + { + $objectManager = new ObjectManager($this); + $this->notSyncedDataProvider = $this->getMockBuilder(NotSyncedDataProviderInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getIds']) + ->getMockForAbstractClass(); + $this->connection = $this->getMockBuilder(ConnectionAdapterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['select', 'fetchAll', 'insertOnDuplicate']) + ->getMockForAbstractClass(); + + $this->grid = $objectManager->getObject( + \Magento\Sales\Model\ResourceModel\Grid::class, + [ + 'notSyncedDataProvider' => $this->notSyncedDataProvider, + 'mainTableName' => $this->mainTable, + 'gridTableName' => $this->gridTable, + 'connection' => $this->connection, + '_tables' => ['sales_order' => $this->mainTable, 'sales_order_grid' => $this->gridTable], + 'columns' => $this->columns + ] + ); + } + + /** + * Test for refreshBySchedule() method + */ + public function testRefreshBySchedule() + { + $notSyncedIds = ['1', '2', '3']; + $fetchResult = ['column_1' => '1', 'column_2' => '2']; + + $this->notSyncedDataProvider->expects($this->atLeastOnce())->method('getIds')->willReturn($notSyncedIds); + $select = $this->getMockBuilder(\Magento\Framework\DB\Select::class) + ->disableOriginalConstructor() + ->setMethods(['from', 'columns', 'where']) + ->getMock(); + $select->expects($this->atLeastOnce())->method('from')->with(['sales_order' => $this->mainTable], []) + ->willReturnSelf(); + $select->expects($this->atLeastOnce())->method('columns')->willReturnSelf(); + $select->expects($this->atLeastOnce())->method('where') + ->with($this->mainTable . '.entity_id IN (?)', $notSyncedIds) + ->willReturnSelf(); + + $this->connection->expects($this->atLeastOnce())->method('select')->willReturn($select); + $this->connection->expects($this->atLeastOnce())->method('fetchAll')->with($select)->willReturn($fetchResult); + $this->connection->expects($this->atLeastOnce())->method('insertOnDuplicate') + ->with($this->gridTable, $fetchResult, array_keys($this->columns)) + ->willReturn(array_count_values($notSyncedIds)); + + $this->grid->refreshBySchedule(); + } +} diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index ac25cdab22f56..89799347fdda0 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -323,6 +323,7 @@ Magento\Sales\Model\Order\Email\Sender\OrderSender Magento\Sales\Model\ResourceModel\Order Magento\Sales\Model\ResourceModel\Order\Collection + Magento\Sales\Model\Order\Email\Container\OrderIdentity @@ -330,6 +331,7 @@ Magento\Sales\Model\Order\Email\Sender\InvoiceSender Magento\Sales\Model\ResourceModel\Order\Invoice Magento\Sales\Model\ResourceModel\Order\Invoice\Collection + Magento\Sales\Model\Order\Email\Container\InvoiceIdentity @@ -337,6 +339,7 @@ Magento\Sales\Model\Order\Email\Sender\ShipmentSender Magento\Sales\Model\ResourceModel\Order\Shipment Magento\Sales\Model\ResourceModel\Order\Shipment\Collection + Magento\Sales\Model\Order\Email\Container\ShipmentIdentity @@ -344,6 +347,7 @@ Magento\Sales\Model\Order\Email\Sender\CreditmemoSender Magento\Sales\Model\ResourceModel\Order\Creditmemo Magento\Sales\Model\ResourceModel\Order\Creditmemo\Collection + Magento\Sales\Model\Order\Email\Container\CreditmemoIdentity diff --git a/app/code/Magento/SalesRule/Model/Quote/ChildrenValidationLocator.php b/app/code/Magento/SalesRule/Model/Quote/ChildrenValidationLocator.php new file mode 100644 index 0000000000000..af1f61c187129 --- /dev/null +++ b/app/code/Magento/SalesRule/Model/Quote/ChildrenValidationLocator.php @@ -0,0 +1,53 @@ + + * [ + * 'ProductType1' => true, + * 'ProductType2' => false + * ] + * + */ + public function __construct( + array $productTypeChildrenValidationMap = [] + ) { + $this->productTypeChildrenValidationMap = $productTypeChildrenValidationMap; + } + + /** + * Checks necessity to validate rule on item's children. + * + * @param QuoteItem $item + * @return bool + */ + public function isChildrenValidationRequired(QuoteItem $item): bool + { + $type = $item->getProduct()->getTypeId(); + if (isset($this->productTypeChildrenValidationMap[$type])) { + return (bool)$this->productTypeChildrenValidationMap[$type]; + } + + return true; + } +} diff --git a/app/code/Magento/SalesRule/Model/RulesApplier.php b/app/code/Magento/SalesRule/Model/RulesApplier.php index 06a4e252bf60e..f771a4f1e3892 100644 --- a/app/code/Magento/SalesRule/Model/RulesApplier.php +++ b/app/code/Magento/SalesRule/Model/RulesApplier.php @@ -6,6 +6,9 @@ namespace Magento\SalesRule\Model; use Magento\Quote\Model\Quote\Address; +use Magento\SalesRule\Model\Quote\ChildrenValidationLocator; +use Magento\Framework\App\ObjectManager; +use Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory; /** * Class RulesApplier @@ -25,19 +28,33 @@ class RulesApplier */ protected $validatorUtility; + /** + * @var ChildrenValidationLocator + */ + private $childrenValidationLocator; + + /** + * @var CalculatorFactory + */ + private $calculatorFactory; + /** * @param \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory $calculatorFactory * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param \Magento\SalesRule\Model\Utility $utility + * @param ChildrenValidationLocator|null $childrenValidationLocator */ public function __construct( \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory $calculatorFactory, \Magento\Framework\Event\ManagerInterface $eventManager, - \Magento\SalesRule\Model\Utility $utility + \Magento\SalesRule\Model\Utility $utility, + ChildrenValidationLocator $childrenValidationLocator = null ) { $this->calculatorFactory = $calculatorFactory; $this->validatorUtility = $utility; $this->_eventManager = $eventManager; + $this->childrenValidationLocator = $childrenValidationLocator + ?: ObjectManager::getInstance()->get(ChildrenValidationLocator::class); } /** @@ -61,6 +78,9 @@ public function applyRules($item, $rules, $skipValidation, $couponCode) } if (!$skipValidation && !$rule->getActions()->validate($item)) { + if (!$this->childrenValidationLocator->isChildrenValidationRequired($item)) { + continue; + } $childItems = $item->getChildren(); $isContinue = true; if (!empty($childItems)) { diff --git a/app/code/Magento/SalesRule/Model/Validator.php b/app/code/Magento/SalesRule/Model/Validator.php index 5c76c534ed03b..5c0f97ae0b08b 100644 --- a/app/code/Magento/SalesRule/Model/Validator.php +++ b/app/code/Magento/SalesRule/Model/Validator.php @@ -506,7 +506,7 @@ public function sortItemsByPriority($items, Address $address = null) foreach ($items as $itemKey => $itemValue) { if ($rule->getActions()->validate($itemValue)) { unset($items[$itemKey]); - array_push($itemsSorted, $itemValue); + $itemsSorted[] = $itemValue; } } } diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/Quote/ChildrenValidationLocatorTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/Quote/ChildrenValidationLocatorTest.php new file mode 100644 index 0000000000000..abb8d791d74c4 --- /dev/null +++ b/app/code/Magento/SalesRule/Test/Unit/Model/Quote/ChildrenValidationLocatorTest.php @@ -0,0 +1,104 @@ +objectManager = new ObjectManager($this); + + $this->productTypeChildrenValidationMap = [ + 'type1' => true, + 'type2' => false, + ]; + + $this->quoteItemMock = $this->getMockBuilder(QuoteItem::class) + ->disableOriginalConstructor() + ->setMethods(['getProduct']) + ->getMockForAbstractClass(); + + $this->productMock = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->setMethods(['getTypeId']) + ->getMock(); + + $this->model = $this->objectManager->getObject( + ChildrenValidationLocator::class, + [ + 'productTypeChildrenValidationMap' => $this->productTypeChildrenValidationMap, + ] + ); + } + + /** + * @dataProvider productTypeDataProvider + * @param string $type + * @param bool $expected + * + * @return void + */ + public function testIsChildrenValidationRequired(string $type, bool $expected): void + { + $this->quoteItemMock->expects($this->once()) + ->method('getProduct') + ->willReturn($this->productMock); + + $this->productMock->expects($this->once()) + ->method('getTypeId') + ->willReturn($type); + + $this->assertEquals($this->model->isChildrenValidationRequired($this->quoteItemMock), $expected); + } + + /** + * @return array + */ + public function productTypeDataProvider(): array + { + return [ + ['type1', true], + ['type2', false], + ['type3', true], + ]; + } +} diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/RulesApplierTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/RulesApplierTest.php index 814048c2ac1d0..37c839d413d4b 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/RulesApplierTest.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/RulesApplierTest.php @@ -6,6 +6,9 @@ namespace Magento\SalesRule\Test\Unit\Model; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class RulesApplierTest extends \PHPUnit\Framework\TestCase { /** @@ -28,6 +31,11 @@ class RulesApplierTest extends \PHPUnit\Framework\TestCase */ protected $validatorUtility; + /** + * @var \Magento\SalesRule\Model\Quote\ChildrenValidationLocator|\PHPUnit_Framework_MockObject_MockObject + */ + protected $childrenValidationLocator; + protected function setUp() { $this->calculatorFactory = $this->createMock( @@ -38,11 +46,15 @@ protected function setUp() \Magento\SalesRule\Model\Utility::class, ['canProcessRule', 'minFix', 'deltaRoundingFix', 'getItemQty'] ); - + $this->childrenValidationLocator = $this->createPartialMock( + \Magento\SalesRule\Model\Quote\ChildrenValidationLocator::class, + ['isChildrenValidationRequired'] + ); $this->rulesApplier = new \Magento\SalesRule\Model\RulesApplier( $this->calculatorFactory, $this->eventManager, - $this->validatorUtility + $this->validatorUtility, + $this->childrenValidationLocator ); } @@ -84,6 +96,10 @@ public function testApplyRulesWhenRuleWithStopRulesProcessingIsUsed($isChildren, $item->setDiscountCalculationPrice($positivePrice); $item->setData('calculation_price', $positivePrice); + $this->childrenValidationLocator->expects($this->any()) + ->method('isChildrenValidationRequired') + ->willReturn(true); + $this->validatorUtility->expects($this->atLeastOnce()) ->method('canProcessRule') ->will($this->returnValue(true)); diff --git a/app/code/Magento/Signifyd/Block/Fingerprint.php b/app/code/Magento/Signifyd/Block/Fingerprint.php index 7afa092b3d0da..db76fc6c94468 100644 --- a/app/code/Magento/Signifyd/Block/Fingerprint.php +++ b/app/code/Magento/Signifyd/Block/Fingerprint.php @@ -85,6 +85,8 @@ public function getSignifydOrderSessionId() */ public function isModuleActive() { - return $this->config->isActive(); + $storeId = $this->quoteSession->getQuote()->getStoreId(); + + return $this->config->isActive($storeId); } } diff --git a/app/code/Magento/Signifyd/Model/Config.php b/app/code/Magento/Signifyd/Model/Config.php index b68380ee15bf3..15d3608bd38c4 100644 --- a/app/code/Magento/Signifyd/Model/Config.php +++ b/app/code/Magento/Signifyd/Model/Config.php @@ -34,13 +34,15 @@ public function __construct(ScopeConfigInterface $scopeConfig) * If this config option set to false no Signifyd integration should be available * (only possibility to configure Signifyd setting in admin) * + * @param int|null $storeId * @return bool */ - public function isActive() + public function isActive($storeId = null): bool { $enabled = $this->scopeConfig->isSetFlag( 'fraud_protection/signifyd/active', - ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE, + $storeId ); return $enabled; } @@ -51,13 +53,15 @@ public function isActive() * @see https://www.signifyd.com/docs/api/#/introduction/authentication * @see https://app.signifyd.com/settings * + * @param int|null $storeId * @return string */ - public function getApiKey() + public function getApiKey($storeId = null): string { $apiKey = $this->scopeConfig->getValue( 'fraud_protection/signifyd/api_key', - ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE, + $storeId ); return $apiKey; } @@ -66,13 +70,15 @@ public function getApiKey() * Base URL to Signifyd REST API. * Usually equals to https://api.signifyd.com/v2 and should not be changed * + * @param int|null $storeId * @return string */ - public function getApiUrl() + public function getApiUrl($storeId = null): string { $apiUrl = $this->scopeConfig->getValue( 'fraud_protection/signifyd/api_url', - ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE, + $storeId ); return $apiUrl; } @@ -80,13 +86,15 @@ public function getApiUrl() /** * If is "true" extra information about interaction with Signifyd API are written to debug.log file * + * @param int|null $storeId * @return bool */ - public function isDebugModeEnabled() + public function isDebugModeEnabled($storeId = null): bool { $debugModeEnabled = $this->scopeConfig->isSetFlag( 'fraud_protection/signifyd/debug', - ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE, + $storeId ); return $debugModeEnabled; } diff --git a/app/code/Magento/Signifyd/Model/SignifydGateway/ApiClient.php b/app/code/Magento/Signifyd/Model/SignifydGateway/ApiClient.php index 0950ca1e22cfa..2d6d57a510ae3 100644 --- a/app/code/Magento/Signifyd/Model/SignifydGateway/ApiClient.php +++ b/app/code/Magento/Signifyd/Model/SignifydGateway/ApiClient.php @@ -36,12 +36,13 @@ public function __construct( * * @param string $url * @param string $method - * @param array $params + * @param array $params + * @param int|null $storeId * @return array */ - public function makeApiCall($url, $method, array $params = []) + public function makeApiCall($url, $method, array $params = [], $storeId = null): array { - $result = $this->requestBuilder->doRequest($url, $method, $params); + $result = $this->requestBuilder->doRequest($url, $method, $params, $storeId); return $result; } diff --git a/app/code/Magento/Signifyd/Model/SignifydGateway/Client/HttpClientFactory.php b/app/code/Magento/Signifyd/Model/SignifydGateway/Client/HttpClientFactory.php index 41006bd7d1e0e..2a9b933b98b5d 100644 --- a/app/code/Magento/Signifyd/Model/SignifydGateway/Client/HttpClientFactory.php +++ b/app/code/Magento/Signifyd/Model/SignifydGateway/Client/HttpClientFactory.php @@ -73,12 +73,13 @@ public function __construct( * @param string $url * @param string $method * @param array $params + * @param int|null $storeId * @return ZendClient */ - public function create($url, $method, array $params = []) + public function create($url, $method, array $params = [], $storeId = null): ZendClient { - $apiKey = $this->getApiKey(); - $apiUrl = $this->buildFullApiUrl($url); + $apiKey = $this->getApiKey($storeId); + $apiUrl = $this->buildFullApiUrl($url, $storeId); $client = $this->createNewClient(); $client->setHeaders( @@ -107,22 +108,24 @@ private function createNewClient() * Signifyd API key for merchant account. * * @see https://www.signifyd.com/docs/api/#/introduction/authentication + * @param int|null $storeId * @return string */ - private function getApiKey() + private function getApiKey($storeId): string { - return $this->config->getApiKey(); + return $this->config->getApiKey($storeId); } /** * Full URL for Singifyd API based on relative URL. * * @param string $url + * @param int|null $storeId * @return string */ - private function buildFullApiUrl($url) + private function buildFullApiUrl($url, $storeId): string { - $baseApiUrl = $this->getBaseApiUrl(); + $baseApiUrl = $this->getBaseApiUrl($storeId); $fullUrl = $baseApiUrl . self::$urlSeparator . ltrim($url, self::$urlSeparator); return $fullUrl; @@ -131,11 +134,12 @@ private function buildFullApiUrl($url) /** * Base Sigifyd API URL without trailing slash. * + * @param int|null $storeId * @return string */ - private function getBaseApiUrl() + private function getBaseApiUrl($storeId): string { - $baseApiUrl = $this->config->getApiUrl(); + $baseApiUrl = $this->config->getApiUrl($storeId); return rtrim($baseApiUrl, self::$urlSeparator); } diff --git a/app/code/Magento/Signifyd/Model/SignifydGateway/Client/RequestBuilder.php b/app/code/Magento/Signifyd/Model/SignifydGateway/Client/RequestBuilder.php index 2ab4395e1990d..ee079a74d345f 100644 --- a/app/code/Magento/Signifyd/Model/SignifydGateway/Client/RequestBuilder.php +++ b/app/code/Magento/Signifyd/Model/SignifydGateway/Client/RequestBuilder.php @@ -5,8 +5,6 @@ */ namespace Magento\Signifyd\Model\SignifydGateway\Client; -use Magento\Framework\HTTP\ZendClient; - /** * Class RequestBuilder * Creates HTTP client, sends request to Signifyd and handles response @@ -50,13 +48,14 @@ public function __construct( * * @param string $url * @param string $method - * @param array $params + * @param array $params + * @param int|null $storeId * @return array */ - public function doRequest($url, $method, array $params = []) + public function doRequest($url, $method, array $params = [], $storeId = null): array { - $client = $this->clientCreator->create($url, $method, $params); - $response = $this->requestSender->send($client); + $client = $this->clientCreator->create($url, $method, $params, $storeId); + $response = $this->requestSender->send($client, $storeId); $result = $this->responseHandler->handle($response); return $result; diff --git a/app/code/Magento/Signifyd/Model/SignifydGateway/Client/RequestSender.php b/app/code/Magento/Signifyd/Model/SignifydGateway/Client/RequestSender.php index 38128a799fd59..a63331e055c1c 100644 --- a/app/code/Magento/Signifyd/Model/SignifydGateway/Client/RequestSender.php +++ b/app/code/Magento/Signifyd/Model/SignifydGateway/Client/RequestSender.php @@ -39,15 +39,16 @@ public function __construct( * debug information is recorded to debug.log. * * @param ZendClient $client + * @param int|null $storeId * @return \Zend_Http_Response * @throws ApiCallException */ - public function send(ZendClient $client) + public function send(ZendClient $client, $storeId = null): \Zend_Http_Response { try { $response = $client->request(); - $this->debuggerFactory->create()->success( + $this->debuggerFactory->create($storeId)->success( $client->getUri(true), $client->getLastRequest(), $response->getStatus() . ' ' . $response->getMessage(), @@ -56,7 +57,7 @@ public function send(ZendClient $client) return $response; } catch (\Exception $e) { - $this->debuggerFactory->create()->failure( + $this->debuggerFactory->create($storeId)->failure( $client->getUri(true), $client->getLastRequest(), $e diff --git a/app/code/Magento/Signifyd/Model/SignifydGateway/Debugger/DebuggerFactory.php b/app/code/Magento/Signifyd/Model/SignifydGateway/Debugger/DebuggerFactory.php index 19408e99ae02e..1e61a313899cc 100644 --- a/app/code/Magento/Signifyd/Model/SignifydGateway/Debugger/DebuggerFactory.php +++ b/app/code/Magento/Signifyd/Model/SignifydGateway/Debugger/DebuggerFactory.php @@ -44,11 +44,12 @@ public function __construct( /** * Create debugger instance * + * @param int|null $storeId * @return DebuggerInterface */ - public function create() + public function create($storeId = null): DebuggerInterface { - if (!$this->config->isDebugModeEnabled()) { + if (!$this->config->isDebugModeEnabled($storeId)) { return $this->objectManager->get(BlackHole::class); } diff --git a/app/code/Magento/Signifyd/Model/SignifydGateway/Gateway.php b/app/code/Magento/Signifyd/Model/SignifydGateway/Gateway.php index ddcaa6cd696f2..9f7a053c58724 100644 --- a/app/code/Magento/Signifyd/Model/SignifydGateway/Gateway.php +++ b/app/code/Magento/Signifyd/Model/SignifydGateway/Gateway.php @@ -5,8 +5,9 @@ */ namespace Magento\Signifyd\Model\SignifydGateway; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Signifyd\Api\CaseRepositoryInterface; use Magento\Signifyd\Model\SignifydGateway\Request\CreateCaseBuilderInterface; -use Magento\Signifyd\Model\SignifydGateway\ApiClient; /** * Signifyd Gateway. @@ -53,18 +54,34 @@ class Gateway */ private $apiClient; + /** + * @var OrderRepositoryInterface + */ + private $orderRepository; + + /** + * @var CaseRepositoryInterface + */ + private $caseRepository; + /** * Gateway constructor. * * @param CreateCaseBuilderInterface $createCaseBuilder * @param ApiClient $apiClient + * @param OrderRepositoryInterface $orderRepository + * @param CaseRepositoryInterface $caseRepository */ public function __construct( CreateCaseBuilderInterface $createCaseBuilder, - ApiClient $apiClient + ApiClient $apiClient, + OrderRepositoryInterface $orderRepository, + CaseRepositoryInterface $caseRepository ) { $this->createCaseBuilder = $createCaseBuilder; $this->apiClient = $apiClient; + $this->orderRepository = $orderRepository; + $this->caseRepository = $caseRepository; } /** @@ -78,11 +95,13 @@ public function __construct( public function createCase($orderId) { $caseParams = $this->createCaseBuilder->build($orderId); + $storeId = $this->getStoreIdFromOrder($orderId); $caseCreationResult = $this->apiClient->makeApiCall( '/cases', 'POST', - $caseParams + $caseParams, + $storeId ); if (!isset($caseCreationResult['investigationId'])) { @@ -102,12 +121,14 @@ public function createCase($orderId) */ public function submitCaseForGuarantee($signifydCaseId) { + $storeId = $this->getStoreIdFromCase($signifydCaseId); $guaranteeCreationResult = $this->apiClient->makeApiCall( '/guarantees', 'POST', [ 'caseId' => $signifydCaseId, - ] + ], + $storeId ); $disposition = $this->processDispositionResult($guaranteeCreationResult); @@ -124,12 +145,14 @@ public function submitCaseForGuarantee($signifydCaseId) */ public function cancelGuarantee($caseId) { + $storeId = $this->getStoreIdFromCase($caseId); $result = $this->apiClient->makeApiCall( '/cases/' . $caseId . '/guarantee', 'PUT', [ 'guaranteeDisposition' => self::GUARANTEE_CANCELED - ] + ], + $storeId ); $disposition = $this->processDispositionResult($result); @@ -172,4 +195,31 @@ private function processDispositionResult(array $result) return $disposition; } + + /** + * Returns store id by case. + * + * @param int $caseId + * @return int|null + */ + private function getStoreIdFromCase(int $caseId) + { + $case = $this->caseRepository->getByCaseId($caseId); + $orderId = $case->getOrderId(); + + return $this->getStoreIdFromOrder($orderId); + } + + /** + * Returns store id from order. + * + * @param int $orderId + * @return int|null + */ + private function getStoreIdFromOrder(int $orderId) + { + $order = $this->orderRepository->get($orderId); + + return $order->getStoreId(); + } } diff --git a/app/code/Magento/Signifyd/Observer/PlaceOrder.php b/app/code/Magento/Signifyd/Observer/PlaceOrder.php index 3798522dbe506..8415bc006b8aa 100644 --- a/app/code/Magento/Signifyd/Observer/PlaceOrder.php +++ b/app/code/Magento/Signifyd/Observer/PlaceOrder.php @@ -55,10 +55,6 @@ public function __construct( */ public function execute(Observer $observer) { - if (!$this->signifydIntegrationConfig->isActive()) { - return; - } - $orders = $this->extractOrders( $observer->getEvent() ); @@ -68,7 +64,10 @@ public function execute(Observer $observer) } foreach ($orders as $order) { - $this->createCaseForOrder($order); + $storeId = $order->getStoreId(); + if ($this->signifydIntegrationConfig->isActive($storeId)) { + $this->createCaseForOrder($order); + } } } diff --git a/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/Client/HttpClientFactoryTest.php b/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/Client/HttpClientFactoryTest.php index 776e8a75b9646..4aefd63355773 100644 --- a/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/Client/HttpClientFactoryTest.php +++ b/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/Client/HttpClientFactoryTest.php @@ -101,14 +101,17 @@ public function testCreateHttpClient() public function testCreateWithParams() { $param = ['id' => 1]; + $storeId = 1; $json = '{"id":1}'; $this->config->expects($this->once()) ->method('getApiKey') + ->with($storeId) ->willReturn('testKey'); $this->config->expects($this->once()) ->method('getApiUrl') + ->with($storeId) ->willReturn(self::$dummy); $this->dataEncoder->expects($this->once()) @@ -121,7 +124,7 @@ public function testCreateWithParams() ->with($this->equalTo($json), 'application/json') ->willReturnSelf(); - $client = $this->httpClient->create('url', 'method', $param); + $client = $this->httpClient->create('url', 'method', $param, $storeId); $this->assertInstanceOf(ZendClient::class, $client); } diff --git a/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/GatewayTest.php b/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/GatewayTest.php index c34e64f469f77..2a05189e0e393 100644 --- a/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/GatewayTest.php +++ b/app/code/Magento/Signifyd/Test/Unit/Model/SignifydGateway/GatewayTest.php @@ -5,7 +5,10 @@ */ namespace Magento\Signifyd\Test\Unit\Model\SignifydGateway; -use \PHPUnit\Framework\TestCase as TestCase; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Signifyd\Api\CaseRepositoryInterface; +use Magento\Signifyd\Api\Data\CaseInterface; use PHPUnit_Framework_MockObject_MockObject as MockObject; use Magento\Signifyd\Model\SignifydGateway\Gateway; use Magento\Signifyd\Model\SignifydGateway\GatewayException; @@ -30,6 +33,16 @@ class GatewayTest extends \PHPUnit\Framework\TestCase */ private $gateway; + /** + * @var OrderRepositoryInterface|MockObject + */ + private $orderRepository; + + /** + * @var CaseRepositoryInterface|MockObject + */ + private $caseRepository; + public function setUp() { $this->createCaseBuilder = $this->getMockBuilder(CreateCaseBuilderInterface::class) @@ -39,16 +52,27 @@ public function setUp() ->disableOriginalConstructor() ->getMock(); + $this->orderRepository = $this->getMockBuilder(OrderRepositoryInterface::class) + ->getMockForAbstractClass(); + + $this->caseRepository= $this->getMockBuilder(CaseRepositoryInterface::class) + ->getMockForAbstractClass(); + $this->gateway = new Gateway( $this->createCaseBuilder, - $this->apiClient + $this->apiClient, + $this->orderRepository, + $this->caseRepository ); } public function testCreateCaseForSpecifiedOrder() { $dummyOrderId = 1; + $dummyStoreId = 2; $dummySignifydInvestigationId = 42; + + $this->withOrderEntity($dummyOrderId, $dummyStoreId); $this->apiClient ->method('makeApiCall') ->willReturn([ @@ -68,7 +92,10 @@ public function testCreateCaseForSpecifiedOrder() public function testCreateCaseCallsValidApiMethod() { $dummyOrderId = 1; + $dummyStoreId = 2; $dummySignifydInvestigationId = 42; + + $this->withOrderEntity($dummyOrderId, $dummyStoreId); $this->createCaseBuilder ->method('build') ->willReturn([]); @@ -79,7 +106,8 @@ public function testCreateCaseCallsValidApiMethod() ->with( $this->equalTo('/cases'), $this->equalTo('POST'), - $this->isType('array') + $this->isType('array'), + $this->equalTo($dummyStoreId) ) ->willReturn([ 'investigationId' => $dummySignifydInvestigationId @@ -92,7 +120,10 @@ public function testCreateCaseCallsValidApiMethod() public function testCreateCaseNormalFlow() { $dummyOrderId = 1; + $dummyStoreId = 2; $dummySignifydInvestigationId = 42; + + $this->withOrderEntity($dummyOrderId, $dummyStoreId); $this->createCaseBuilder ->method('build') ->willReturn([]); @@ -113,7 +144,10 @@ public function testCreateCaseNormalFlow() public function testCreateCaseWithFailedApiCall() { $dummyOrderId = 1; + $dummyStoreId = 2; $apiCallFailureMessage = 'Api call failed'; + + $this->withOrderEntity($dummyOrderId, $dummyStoreId); $this->createCaseBuilder ->method('build') ->willReturn([]); @@ -129,6 +163,9 @@ public function testCreateCaseWithFailedApiCall() public function testCreateCaseWithMissedResponseRequiredData() { $dummyOrderId = 1; + $dummyStoreId = 2; + + $this->withOrderEntity($dummyOrderId, $dummyStoreId); $this->createCaseBuilder ->method('build') ->willReturn([]); @@ -145,7 +182,10 @@ public function testCreateCaseWithMissedResponseRequiredData() public function testCreateCaseWithAdditionalResponseData() { $dummyOrderId = 1; + $dummyStoreId = 2; $dummySignifydInvestigationId = 42; + + $this->withOrderEntity($dummyOrderId, $dummyStoreId); $this->createCaseBuilder ->method('build') ->willReturn([]); @@ -167,8 +207,10 @@ public function testCreateCaseWithAdditionalResponseData() public function testSubmitCaseForGuaranteeCallsValidApiMethod() { $dummySygnifydCaseId = 42; + $dummyStoreId = 1; $dummyDisposition = 'APPROVED'; + $this->withCaseEntity($dummySygnifydCaseId, $dummyStoreId); $this->apiClient ->expects($this->atLeastOnce()) ->method('makeApiCall') @@ -177,7 +219,8 @@ public function testSubmitCaseForGuaranteeCallsValidApiMethod() $this->equalTo('POST'), $this->equalTo([ 'caseId' => $dummySygnifydCaseId - ]) + ]), + $this->equalTo($dummyStoreId) )->willReturn([ 'disposition' => $dummyDisposition ]); @@ -189,8 +232,10 @@ public function testSubmitCaseForGuaranteeCallsValidApiMethod() public function testSubmitCaseForGuaranteeWithFailedApiCall() { $dummySygnifydCaseId = 42; + $dummyStoreId = 1; $apiCallFailureMessage = 'Api call failed'; + $this->withCaseEntity($dummySygnifydCaseId, $dummyStoreId); $this->apiClient ->method('makeApiCall') ->willThrowException(new ApiCallException($apiCallFailureMessage)); @@ -204,10 +249,12 @@ public function testSubmitCaseForGuaranteeWithFailedApiCall() public function testSubmitCaseForGuaranteeReturnsDisposition() { $dummySygnifydCaseId = 42; + $dummyStoreId = 1; $dummyDisposition = 'APPROVED'; $dummyGuaranteeId = 123; $dummyRereviewCount = 0; + $this->withCaseEntity($dummySygnifydCaseId, $dummyStoreId); $this->apiClient ->method('makeApiCall') ->willReturn([ @@ -227,9 +274,11 @@ public function testSubmitCaseForGuaranteeReturnsDisposition() public function testSubmitCaseForGuaranteeWithMissedDisposition() { $dummySygnifydCaseId = 42; + $dummyStoreId = 1; $dummyGuaranteeId = 123; $dummyRereviewCount = 0; + $this->withCaseEntity($dummySygnifydCaseId, $dummyStoreId); $this->apiClient ->method('makeApiCall') ->willReturn([ @@ -244,8 +293,10 @@ public function testSubmitCaseForGuaranteeWithMissedDisposition() public function testSubmitCaseForGuaranteeWithUnexpectedDisposition() { $dummySygnifydCaseId = 42; + $dummyStoreId = 1; $dummyUnexpectedDisposition = 'UNEXPECTED'; + $this->withCaseEntity($dummySygnifydCaseId, $dummyStoreId); $this->apiClient ->method('makeApiCall') ->willReturn([ @@ -263,7 +314,9 @@ public function testSubmitCaseForGuaranteeWithUnexpectedDisposition() public function testSubmitCaseForGuaranteeWithExpectedDisposition($dummyExpectedDisposition) { $dummySygnifydCaseId = 42; + $dummyStoreId = 1; + $this->withCaseEntity($dummySygnifydCaseId, $dummyStoreId); $this->apiClient ->method('makeApiCall') ->willReturn([ @@ -290,11 +343,20 @@ public function testSubmitCaseForGuaranteeWithExpectedDisposition($dummyExpected public function testCancelGuarantee() { $caseId = 123; + $dummyStoreId = 1; + $this->withCaseEntity($caseId, $dummyStoreId); $this->apiClient->expects(self::once()) ->method('makeApiCall') - ->with('/cases/' . $caseId . '/guarantee', 'PUT', ['guaranteeDisposition' => Gateway::GUARANTEE_CANCELED]) - ->willReturn(['disposition' => Gateway::GUARANTEE_CANCELED]); + ->with( + '/cases/' . $caseId . '/guarantee', + 'PUT', + ['guaranteeDisposition' => Gateway::GUARANTEE_CANCELED], + $dummyStoreId + ) + ->willReturn( + ['disposition' => Gateway::GUARANTEE_CANCELED] + ); $result = $this->gateway->cancelGuarantee($caseId); self::assertEquals(Gateway::GUARANTEE_CANCELED, $result); @@ -310,10 +372,17 @@ public function testCancelGuarantee() public function testCancelGuaranteeWithUnexpectedDisposition() { $caseId = 123; + $dummyStoreId = 1; + $this->withCaseEntity($caseId, $dummyStoreId); $this->apiClient->expects(self::once()) ->method('makeApiCall') - ->with('/cases/' . $caseId . '/guarantee', 'PUT', ['guaranteeDisposition' => Gateway::GUARANTEE_CANCELED]) + ->with( + '/cases/' . $caseId . '/guarantee', + 'PUT', + ['guaranteeDisposition' => Gateway::GUARANTEE_CANCELED], + $dummyStoreId + ) ->willReturn(['disposition' => Gateway::GUARANTEE_DECLINED]); $result = $this->gateway->cancelGuarantee($caseId); @@ -331,4 +400,46 @@ public function supportedGuaranteeDispositionsProvider() 'UNREQUESTED' => ['UNREQUESTED'], ]; } + + /** + * Specifies order entity mock execution. + * + * @param int $orderId + * @param int $storeId + * @return void + */ + private function withOrderEntity(int $orderId, int $storeId): void + { + $orderEntity = $this->getMockBuilder(OrderInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $orderEntity->method('getStoreId') + ->willReturn($storeId); + $this->orderRepository->method('get') + ->with($orderId) + ->willReturn($orderEntity); + } + + /** + * Specifies case entity mock execution. + * + * @param int $caseId + * @param int $storeId + * @return void + */ + private function withCaseEntity(int $caseId, int $storeId): void + { + $orderId = 1; + + $caseEntity = $this->getMockBuilder(CaseInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $caseEntity->method('getOrderId') + ->willReturn($orderId); + $this->caseRepository->method('getByCaseId') + ->with($caseId) + ->willReturn($caseEntity); + + $this->withOrderEntity($orderId, $storeId); + } } diff --git a/app/code/Magento/Signifyd/Test/Unit/Observer/PlaceOrderTest.php b/app/code/Magento/Signifyd/Test/Unit/Observer/PlaceOrderTest.php index e2870953ec280..4e7edddf7b948 100644 --- a/app/code/Magento/Signifyd/Test/Unit/Observer/PlaceOrderTest.php +++ b/app/code/Magento/Signifyd/Test/Unit/Observer/PlaceOrderTest.php @@ -97,7 +97,10 @@ protected function setUp() */ public function testExecuteWithDisabledModule() { - $this->withActiveSignifydIntegration(false); + $orderId = 1; + $storeId = 2; + $this->withActiveSignifydIntegration(false, $storeId); + $this->withOrderEntity($orderId, $storeId); $this->creationService->expects(self::never()) ->method('createForOrder'); @@ -113,7 +116,7 @@ public function testExecuteWithDisabledModule() public function testExecuteWithoutOrder() { $this->withActiveSignifydIntegration(true); - $this->withOrderEntity(null); + $this->withOrderEntity(null, null); $this->creationService->expects(self::never()) ->method('createForOrder'); @@ -129,8 +132,9 @@ public function testExecuteWithoutOrder() public function testExecuteWithOfflinePayment() { $orderId = 1; - $this->withActiveSignifydIntegration(true); - $this->withOrderEntity($orderId); + $storeId = 2; + $this->withActiveSignifydIntegration(true, $storeId); + $this->withOrderEntity($orderId, $storeId); $this->withAvailablePaymentMethod(false); $this->creationService->expects(self::never()) @@ -147,10 +151,11 @@ public function testExecuteWithOfflinePayment() public function testExecuteWithFailedCaseCreation() { $orderId = 1; + $storeId = 2; $exceptionMessage = __('Case with the same order id already exists.'); - $this->withActiveSignifydIntegration(true); - $this->withOrderEntity($orderId); + $this->withActiveSignifydIntegration(true, $storeId); + $this->withOrderEntity($orderId, $storeId); $this->withAvailablePaymentMethod(true); $this->creationService->method('createForOrder') @@ -172,9 +177,10 @@ public function testExecuteWithFailedCaseCreation() public function testExecute() { $orderId = 1; + $storeId = 2; - $this->withActiveSignifydIntegration(true); - $this->withOrderEntity($orderId); + $this->withActiveSignifydIntegration(true, $storeId); + $this->withOrderEntity($orderId, $storeId); $this->withAvailablePaymentMethod(true); $this->creationService @@ -190,10 +196,11 @@ public function testExecute() /** * Specifies order entity mock execution. * - * @param int $orderId + * @param int|null $orderId + * @param int|null $storeId * @return void */ - private function withOrderEntity($orderId) + private function withOrderEntity($orderId, $storeId): void { $this->orderEntity = $this->getMockBuilder(OrderInterface::class) ->disableOriginalConstructor() @@ -201,6 +208,8 @@ private function withOrderEntity($orderId) $this->orderEntity->method('getEntityId') ->willReturn($orderId); + $this->orderEntity->method('getStoreId') + ->willReturn($storeId); $this->observer->method('getEvent') ->willReturn($this->event); @@ -214,11 +223,13 @@ private function withOrderEntity($orderId) * Specifies config mock execution. * * @param bool $isActive + * @param int|null $storeId * @return void */ - private function withActiveSignifydIntegration($isActive) + private function withActiveSignifydIntegration(bool $isActive, $storeId = null): void { $this->config->method('isActive') + ->with($storeId) ->willReturn($isActive); } diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php index edae49b77ff27..513ba04802985 100644 --- a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php +++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php @@ -53,6 +53,10 @@ class Create implements ProcessorInterface /** * The event manager. * + * @deprecated logic moved inside of "afterSave" method + * \Magento\Store\Model\Website::afterSave + * \Magento\Store\Model\Group::afterSave + * \Magento\Store\Model\Store::afterSave * @var ManagerInterface */ private $eventManager; @@ -182,8 +186,6 @@ private function createGroups(array $items, array $data) $group->setDefaultStoreId($store->getStoreId()); $group->setWebsite($website); $group->getResource()->save($group); - - $this->eventManager->dispatch('store_group_save', ['group' => $group]); }); } } diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Delete.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Delete.php index 8660a0ba7152d..475c15122773e 100644 --- a/app/code/Magento/Store/Model/Config/Importer/Processor/Delete.php +++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Delete.php @@ -168,10 +168,7 @@ private function deleteStores(array $items) foreach ($items as $storeCode) { $store = $this->storeRepository->get($storeCode); - $store->getResource()->delete($store); - $store->getResource()->addCommitCallback(function () use ($store) { - $this->eventManager->dispatch('store_delete', ['store' => $store]); - }); + $store->delete(); } } diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Update.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Update.php index 35f3957b168d7..155506291e59d 100644 --- a/app/code/Magento/Store/Model/Config/Importer/Processor/Update.php +++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Update.php @@ -176,10 +176,7 @@ private function updateStores(array $items, array $data) $store->setGroup($group); } - $store->getResource()->save($store); - $store->getResource()->addCommitCallback(function () use ($store) { - $this->eventManager->dispatch('store_edit', ['store' => $store]); - }); + $store->save(); } } @@ -214,11 +211,7 @@ private function updateGroups(array $items, array $data) if ($website && $website->getId() != $group->getWebsiteId()) { $group->setWebsite($website); } - - $group->getResource()->save($group); - $group->getResource()->addCommitCallback(function () use ($group) { - $this->eventManager->dispatch('store_group_save', ['group' => $group]); - }); + $group->save(); } } diff --git a/app/code/Magento/Store/Model/Group.php b/app/code/Magento/Store/Model/Group.php index 01f56fb9e0566..ccc3c65491422 100644 --- a/app/code/Magento/Store/Model/Group.php +++ b/app/code/Magento/Store/Model/Group.php @@ -95,6 +95,11 @@ class Group extends \Magento\Framework\Model\AbstractExtensibleModel implements */ protected $_storeManager; + /** + * @var \Magento\Framework\Event\ManagerInterface + */ + private $eventManager; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -106,6 +111,7 @@ class Group extends \Magento\Framework\Model\AbstractExtensibleModel implements * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data + * @param \Magento\Framework\Event\ManagerInterface|null $eventManager * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -118,11 +124,14 @@ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, - array $data = [] + array $data = [], + \Magento\Framework\Event\ManagerInterface $eventManager = null ) { $this->_configDataResource = $configDataResource; $this->_storeListFactory = $storeListFactory; $this->_storeManager = $storeManager; + $this->eventManager = $eventManager ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Event\ManagerInterface::class); parent::__construct( $context, $registry, @@ -405,6 +414,11 @@ public function beforeDelete() */ public function afterDelete() { + $group = $this; + $this->getResource()->addCommitCallback(function () use ($group) { + $this->_storeManager->reinitStores(); + $this->eventManager->dispatch($this->_eventPrefix . '_delete', ['group' => $group]); + }); $result = parent::afterDelete(); if ($this->getId() === $this->getWebsite()->getDefaultGroupId()) { @@ -421,6 +435,19 @@ public function afterDelete() return $result; } + /** + * @inheritdoc + */ + public function afterSave() + { + $group = $this; + $this->getResource()->addCommitCallback(function () use ($group) { + $this->_storeManager->reinitStores(); + $this->eventManager->dispatch($this->_eventPrefix . '_save', ['group' => $group]); + }); + return parent::afterSave(); + } + /** * Get/Set isReadOnly flag * diff --git a/app/code/Magento/Store/Model/PathConfig.php b/app/code/Magento/Store/Model/PathConfig.php index dfe4eee31f9a2..6eeb93d7475fa 100644 --- a/app/code/Magento/Store/Model/PathConfig.php +++ b/app/code/Magento/Store/Model/PathConfig.php @@ -83,6 +83,8 @@ public function shouldBeSecure($path) */ public function getDefaultPath() { - return $this->scopeConfig->getValue('web/default/front', ScopeInterface::SCOPE_STORE); + $store = $this->storeManager->getStore(); + $value = $this->scopeConfig->getValue('web/default/front', ScopeInterface::SCOPE_STORE, $store); + return $value; } } diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php index bd90bb9f09496..6e749df6a768d 100644 --- a/app/code/Magento/Store/Model/Store.php +++ b/app/code/Magento/Store/Model/Store.php @@ -320,6 +320,11 @@ class Store extends AbstractExtensibleModel implements */ private $urlModifier; + /** + * @var \Magento\Framework\Event\ManagerInterface + */ + private $eventManager; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -345,6 +350,7 @@ class Store extends AbstractExtensibleModel implements * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param bool $isCustomEntryPoint * @param array $data optional generic object data + * @param \Magento\Framework\Event\ManagerInterface|null $eventManager * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -372,7 +378,8 @@ public function __construct( \Magento\Store\Api\WebsiteRepositoryInterface $websiteRepository, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, $isCustomEntryPoint = false, - array $data = [] + array $data = [], + \Magento\Framework\Event\ManagerInterface $eventManager = null ) { $this->_coreFileStorageDatabase = $coreFileStorageDatabase; $this->_config = $config; @@ -391,6 +398,8 @@ public function __construct( $this->_currencyInstalled = $currencyInstalled; $this->groupRepository = $groupRepository; $this->websiteRepository = $websiteRepository; + $this->eventManager = $eventManager ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Event\ManagerInterface::class); parent::__construct( $context, $registry, @@ -1049,6 +1058,15 @@ public function getWebsiteId() public function afterSave() { $this->_storeManager->reinitStores(); + if ($this->isObjectNew()) { + $event = $this->_eventPrefix . '_add'; + } else { + $event = $this->_eventPrefix . '_edit'; + } + $store = $this; + $this->getResource()->addCommitCallback(function () use ($event, $store) { + $this->eventManager->dispatch($event, ['store' => $store]); + }); return parent::afterSave(); } @@ -1238,6 +1256,11 @@ public function beforeDelete() */ public function afterDelete() { + $store = $this; + $this->getResource()->addCommitCallback(function () use ($store) { + $this->_storeManager->reinitStores(); + $this->eventManager->dispatch($this->_eventPrefix . '_delete', ['store' => $store]); + }); parent::afterDelete(); $this->_configCacheType->clean(); @@ -1252,6 +1275,7 @@ public function afterDelete() $this->getGroup()->setDefaultStoreId($defaultId); $this->getGroup()->save(); } + return $this; } diff --git a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php index 9c7cc648cf8af..2c2b0b00aec43 100644 --- a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php @@ -325,10 +325,6 @@ public function testRunGroup() return $function(); }); - $this->eventManagerMock->expects($this->once()) - ->method('dispatch') - ->with('store_group_save', ['group' => $this->groupMock]); - $this->processor->run($this->data); } @@ -382,10 +378,6 @@ public function testRunStore() return $function(); }); - $this->eventManagerMock->expects($this->once()) - ->method('dispatch') - ->with('store_add', ['store' => $this->storeMock]); - $this->processor->run($this->data); } diff --git a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/DeleteTest.php b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/DeleteTest.php index d16a4a70b00aa..c373643fa03ac 100644 --- a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/DeleteTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/DeleteTest.php @@ -244,8 +244,6 @@ public function testRun() ->method('get') ->with('test') ->willReturn($this->storeMock); - $this->storeResourceMock->expects($this->once()) - ->method('addCommitCallback'); $this->registryMock->expects($this->once()) ->method('unregister') diff --git a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/UpdateTest.php b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/UpdateTest.php index 3b0b932e31d46..99722ab7f855c 100644 --- a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/UpdateTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/UpdateTest.php @@ -175,7 +175,7 @@ public function testRun() $updateData[ScopeInterface::SCOPE_STORES], ], ]); - $this->websiteMock->expects($this->exactly(4)) + $this->websiteMock->expects($this->atLeastOnce()) ->method('getResource') ->willReturn($this->websiteResourceMock); $this->websiteMock->expects($this->once()) @@ -203,7 +203,7 @@ public function testRun() $this->groupFactoryMock->expects($this->exactly(3)) ->method('create') ->willReturn($this->groupMock); - $this->groupMock->expects($this->exactly(5)) + $this->groupMock->expects($this->atLeastOnce()) ->method('getResource') ->willReturn($this->groupResourceMock); $this->groupMock->expects($this->once()) @@ -227,7 +227,7 @@ public function testRun() $this->storeFactoryMock->expects($this->exactly(2)) ->method('create') ->willReturn($this->storeMock); - $this->storeMock->expects($this->exactly(4)) + $this->storeMock->expects($this->atLeastOnce()) ->method('getResource') ->willReturn($this->storeResourceMock); $this->storeMock->expects($this->once()) @@ -244,11 +244,9 @@ public function testRun() $this->storeMock->expects($this->once()) ->method('setData') ->with($updateData[ScopeInterface::SCOPE_STORES]['test']); - $this->storeResourceMock->expects($this->once()) + $this->storeMock->expects($this->once()) ->method('save') - ->with($this->storeMock); - $this->storeResourceMock->expects($this->once()) - ->method('addCommitCallback'); + ->willReturnSelf(); $this->model->run($data); } diff --git a/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php b/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php index dfda76372df1f..383c97a166d34 100644 --- a/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php +++ b/app/code/Magento/Swatches/Controller/Adminhtml/Product/Attribute/Plugin/Save.php @@ -11,7 +11,7 @@ use Magento\Swatches\Model\Swatch; /** - * Class Save + * Plugin for product attribute save controller. */ class Save { @@ -24,7 +24,17 @@ class Save public function beforeDispatch(Attribute\Save $subject, RequestInterface $request) { $data = $request->getPostValue(); + if (isset($data['frontend_input'])) { + //Data is serialized to overcome issues caused by max_input_vars value if it's modification is unavailable. + //See subject controller code and comments for more info. + if (isset($data['serialized_swatch_values']) + && in_array($data['frontend_input'], ['swatch_visual', 'swatch_text']) + ) { + $data['serialized_options'] = $data['serialized_swatch_values']; + unset($data['serialized_swatch_values']); + } + switch ($data['frontend_input']) { case 'swatch_visual': $data[Swatch::SWATCH_INPUT_TYPE_KEY] = Swatch::SWATCH_INPUT_TYPE_VISUAL; diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index 1187e6bc4fdaa..01411523108cf 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -414,6 +414,8 @@ define([ }; $(function () { + var editForm = $('#edit_form'); + $('#frontend_input').bind('change', function () { swatchProductAttributes.bindAttributeInputType(); }); @@ -427,6 +429,34 @@ define([ $('.attribute-popup .collapse, [data-role="advanced_fieldset-content"]') .collapsable() .collapse('hide'); + + editForm.on('submit', function () { + var activePanel, + swatchValues = [], + swatchVisualPanel = $('#swatch-visual-options-panel'), + swatchTextPanel = $('#swatch-text-options-panel'); + + activePanel = swatchTextPanel.is(':visible') ? swatchTextPanel : swatchVisualPanel; + + activePanel + .find('table input') + .each(function () { + swatchValues.push(this.name + '=' + $(this).val()); + }); + + $('') + .attr({ + type: 'hidden', + name: 'serialized_swatch_values' + }) + .val(JSON.stringify(swatchValues)) + .prependTo(editForm); + + [swatchVisualPanel, swatchTextPanel].forEach(function (el) { + $(el).find('table') + .replaceWith($('
').text($.mage.__('Sending swatch values as package.'))); + }); + }); }); window.saveAttributeInNewSet = swatchProductAttributes.saveAttributeInNewSet; diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php index de884be6bc839..4aea7ab4c5a7c 100755 --- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php +++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php @@ -152,12 +152,23 @@ protected function clearValues(Address\Total $total) $total->setBaseTotalAmount('subtotal', 0); $total->setTotalAmount('tax', 0); $total->setBaseTotalAmount('tax', 0); + $total->setTotalAmount('shipping', 0); + $total->setBaseTotalAmount('shipping', 0); $total->setTotalAmount('discount_tax_compensation', 0); $total->setBaseTotalAmount('discount_tax_compensation', 0); $total->setTotalAmount('shipping_discount_tax_compensation', 0); $total->setBaseTotalAmount('shipping_discount_tax_compensation', 0); $total->setSubtotalInclTax(0); $total->setBaseSubtotalInclTax(0); + $total->setShippingInclTax(0); + $total->setBaseShippingInclTax(0); + $total->setShippingTaxAmount(0); + $total->setBaseShippingTaxAmount(0); + $total->setShippingAmountForDiscount(0); + $total->setBaseShippingAmountForDiscount(0); + $total->setBaseShippingAmountForDiscount(0); + $total->setTotalAmount('extra_tax', 0); + $total->setBaseTotalAmount('extra_tax', 0); } /** diff --git a/app/code/Magento/Theme/view/adminhtml/web/favicon.ico b/app/code/Magento/Theme/view/adminhtml/web/favicon.ico index 1cb7c7713718b..d467f2bcbaed4 100644 Binary files a/app/code/Magento/Theme/view/adminhtml/web/favicon.ico and b/app/code/Magento/Theme/view/adminhtml/web/favicon.ico differ diff --git a/app/code/Magento/Theme/view/frontend/web/favicon.ico b/app/code/Magento/Theme/view/frontend/web/favicon.ico index 1cb7c7713718b..d467f2bcbaed4 100644 Binary files a/app/code/Magento/Theme/view/frontend/web/favicon.ico and b/app/code/Magento/Theme/view/frontend/web/favicon.ico differ diff --git a/app/code/Magento/Theme/view/install/web/favicon.ico b/app/code/Magento/Theme/view/install/web/favicon.ico index 1cb7c7713718b..d467f2bcbaed4 100644 Binary files a/app/code/Magento/Theme/view/install/web/favicon.ico and b/app/code/Magento/Theme/view/install/web/favicon.ico differ diff --git a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/Formatter.js b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/Formatter.js index 0cbca75ec504b..5f05d3f3015ad 100644 --- a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/Formatter.js +++ b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/Formatter.js @@ -445,7 +445,7 @@ childCount = getChildCount(node); // Remove empty nodes but only if there is multiple wrappers and they are not block - // elements so never remove single

since that would remove the currrent empty block element where the caret is at + // elements so never remove single

since that would remove the current empty block element where the caret is at if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) { dom.remove(node, 1); return; diff --git a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/dom/DOMUtils.js b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/dom/DOMUtils.js index 783dbea1cacb9..eb8b4b7ab5d78 100644 --- a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/dom/DOMUtils.js +++ b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/dom/DOMUtils.js @@ -1106,7 +1106,7 @@ /** * Returns a unique id. This can be useful when generating elements on the fly. - * This method will not check if the element allready exists. + * This method will not check if the element already exists. * * @method uniqueId * @param {String} p Optional prefix to add infront of all ids defaults to "mce_". diff --git a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_jquery_src.js b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_jquery_src.js index b16d0e3ffdbb4..2daf1620a918e 100644 --- a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_jquery_src.js +++ b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_jquery_src.js @@ -14451,7 +14451,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { childCount = getChildCount(node); // Remove empty nodes but only if there is multiple wrappers and they are not block - // elements so never remove single

since that would remove the currrent empty block element where the caret is at + // elements so never remove single

since that would remove the current empty block element where the caret is at if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) { dom.remove(node, 1); return; diff --git a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_prototype_src.js b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_prototype_src.js index 1c7b76cf75c8b..44b3010b0adfd 100644 --- a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_prototype_src.js +++ b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_prototype_src.js @@ -15301,7 +15301,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { childCount = getChildCount(node); // Remove empty nodes but only if there is multiple wrappers and they are not block - // elements so never remove single

since that would remove the currrent empty block element where the caret is at + // elements so never remove single

since that would remove the current empty block element where the caret is at if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) { dom.remove(node, 1); return; diff --git a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_src.js b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_src.js index a1ce5c5d8c32f..46ba27e60f419 100644 --- a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_src.js +++ b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_src.js @@ -15275,7 +15275,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { childCount = getChildCount(node); // Remove empty nodes but only if there is multiple wrappers and they are not block - // elements so never remove single

since that would remove the currrent empty block element where the caret is at + // elements so never remove single

since that would remove the current empty block element where the caret is at if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) { dom.remove(node, 1); return; diff --git a/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php b/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php index 971da30d1009a..578ebe4d441d9 100644 --- a/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php +++ b/app/code/Magento/Ui/DataProvider/AbstractDataProvider.php @@ -292,6 +292,6 @@ public function setConfigData($config) */ public function getAllIds() { - return $this->collection->getAllIds(); + return $this->getCollection()->getAllIds(); } } diff --git a/app/code/Magento/Ui/view/base/web/js/modal/modal.js b/app/code/Magento/Ui/view/base/web/js/modal/modal.js index af2b31f7eab43..6c9b4b89bec7a 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/modal.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/modal.js @@ -336,11 +336,12 @@ define([ * Set z-index and margin for modal and overlay. */ _setActive: function () { - var zIndex = this.modal.zIndex(); + var zIndex = this.modal.zIndex(), + baseIndex = zIndex + this._getVisibleCount(); + this.overlay.zIndex(++baseIndex); this.prevOverlayIndex = this.overlay.zIndex(); - this.modal.zIndex(zIndex + this._getVisibleCount()); - this.overlay.zIndex(zIndex + (this._getVisibleCount() - 1)); + this.modal.zIndex(this.overlay.zIndex() + 1); if (this._getVisibleSlideCount()) { this.modal.css('marginLeft', this.options.modalLeftMargin * this._getVisibleSlideCount()); @@ -354,7 +355,14 @@ define([ this.modal.removeAttr('style'); if (this.overlay) { - this.overlay.zIndex(this.prevOverlayIndex); + // In cases when one modal is closed but there is another modal open (e.g. admin notifications) + // to avoid collisions between overlay and modal zIndexes + // overlay zIndex is set to be less than modal one + if (this._getVisibleCount() === 1) { + this.overlay.zIndex(this.prevOverlayIndex - 1); + } else { + this.overlay.zIndex(this.prevOverlayIndex); + } } }, diff --git a/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php b/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php index 195c0fc10dc07..38025f21cdab1 100644 --- a/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php +++ b/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php @@ -79,7 +79,7 @@ public function getUrlRewriteId() /** * @param int $urlRewriteId - * @return int + * @return $this */ public function setUrlRewriteId($urlRewriteId) { diff --git a/app/code/Magento/User/Model/Backend/Config/ObserverConfig.php b/app/code/Magento/User/Model/Backend/Config/ObserverConfig.php index c1b7e6a1110f7..6d921dfdcdd65 100644 --- a/app/code/Magento/User/Model/Backend/Config/ObserverConfig.php +++ b/app/code/Magento/User/Model/Backend/Config/ObserverConfig.php @@ -72,7 +72,7 @@ public function getAdminPasswordLifetime() } /** - * Get admin maxiumum security failures from config + * Get admin maximum security failures from config * * @return int */ diff --git a/app/code/Magento/Vault/etc/db_schema.xml b/app/code/Magento/Vault/etc/db_schema.xml index 6975369145776..ed1f2adba2142 100644 --- a/app/code/Magento/Vault/etc/db_schema.xml +++ b/app/code/Magento/Vault/etc/db_schema.xml @@ -30,12 +30,12 @@ - + - + diff --git a/app/code/Magento/Vault/etc/db_schema_whitelist.json b/app/code/Magento/Vault/etc/db_schema_whitelist.json index 256bfcb458c7e..9b5e740fd16e8 100644 --- a/app/code/Magento/Vault/etc/db_schema_whitelist.json +++ b/app/code/Magento/Vault/etc/db_schema_whitelist.json @@ -16,7 +16,9 @@ "constraint": { "PRIMARY": true, "VAULT_PAYMENT_TOKEN_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID": true, + "VAULT_PAYMENT_TOKEN_PAYMENT_METHOD_CODE_CSTR_ID_GATEWAY_TOKEN": true, "UNQ_54DCE14AEAEA03B587F9EF723EB10A10": true, + "VAULT_PAYMENT_TOKEN_PUBLIC_HASH": true, "VAULT_PAYMENT_TOKEN_HASH_UNIQUE_INDEX_PUBLIC_HASH": true } }, @@ -31,4 +33,4 @@ "FK_4ED894655446D385894580BECA993862": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/Webapi/Controller/Soap.php b/app/code/Magento/Webapi/Controller/Soap.php index 32e1cdb9c888d..215ae4752aa1d 100644 --- a/app/code/Magento/Webapi/Controller/Soap.php +++ b/app/code/Magento/Webapi/Controller/Soap.php @@ -51,6 +51,11 @@ class Soap implements \Magento\Framework\App\FrontControllerInterface */ protected $_errorProcessor; + /** + * @var \Magento\Framework\App\State + */ + protected $_appState; + /** * @var \Magento\Framework\Locale\ResolverInterface */ diff --git a/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php b/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php index 72cbbe7481cfa..486275ac69dc5 100644 --- a/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php +++ b/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php @@ -107,7 +107,7 @@ public function __construct( * * @param string $operation * @param array $arguments - * @return \stdClass|null + * @return array * @throws WebapiException * @throws \LogicException * @throws AuthorizationException diff --git a/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php b/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php index 94196c9b86534..d89513b50c9c5 100644 --- a/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php +++ b/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php @@ -132,6 +132,11 @@ private function isTokenExpired(Token $token): bool // other user-type tokens are considered always valid return false; } + + if (empty($tokenTtl)) { + return false; + } + if ($this->dateTime->strToTime($token->getCreatedAt()) < ($this->date->gmtTimestamp() - $tokenTtl * 3600)) { return true; } diff --git a/app/code/Magento/Webapi/Model/Plugin/GuestAuthorization.php b/app/code/Magento/Webapi/Model/Plugin/GuestAuthorization.php index 4eb8b131e0718..78082fab8bd9c 100644 --- a/app/code/Magento/Webapi/Model/Plugin/GuestAuthorization.php +++ b/app/code/Magento/Webapi/Model/Plugin/GuestAuthorization.php @@ -19,7 +19,7 @@ class GuestAuthorization * Check if resource for which access is needed has anonymous permissions defined in webapi config. * * @param \Magento\Framework\Authorization $subject - * @param callable $proceed + * @param \Closure $proceed * @param string $resource * @param string $privilege * @return bool true If resource permission is anonymous, diff --git a/app/code/Magento/Webapi/Model/Rest/Config.php b/app/code/Magento/Webapi/Model/Rest/Config.php index 3fd8c640fb3b7..aa5dfdd7a7fd9 100644 --- a/app/code/Magento/Webapi/Model/Rest/Config.php +++ b/app/code/Magento/Webapi/Model/Rest/Config.php @@ -21,6 +21,7 @@ class Config const HTTP_METHOD_DELETE = 'DELETE'; const HTTP_METHOD_PUT = 'PUT'; const HTTP_METHOD_POST = 'POST'; + const HTTP_METHOD_PATCH = 'PATCH'; /**#@-*/ /**#@+ diff --git a/app/code/Magento/Webapi/Model/Soap/Server.php b/app/code/Magento/Webapi/Model/Soap/Server.php index aa7a4041ae415..be2dec2860772 100644 --- a/app/code/Magento/Webapi/Model/Soap/Server.php +++ b/app/code/Magento/Webapi/Model/Soap/Server.php @@ -31,7 +31,7 @@ class Server const REQUEST_PARAM_LIST_WSDL = 'wsdl_list'; /** - * @var \Magento\Framework\App\AreaLIst + * @var \Magento\Framework\App\AreaList */ protected $_areaList; diff --git a/app/code/Magento/Webapi/Test/Unit/Model/Soap/FaultTest.php b/app/code/Magento/Webapi/Test/Unit/Model/Soap/FaultTest.php index 1ac7943fa6484..8d4cd8561520c 100644 --- a/app/code/Magento/Webapi/Test/Unit/Model/Soap/FaultTest.php +++ b/app/code/Magento/Webapi/Test/Unit/Model/Soap/FaultTest.php @@ -125,7 +125,7 @@ public function testToXmlDeveloperModeOff() public function testToXmlDeveloperModeOn() { $this->_appStateMock->expects($this->any())->method('getMode')->will($this->returnValue('developer')); - $actualXml = $this->_soapFault->toXml(true); + $actualXml = $this->_soapFault->toXml(); $this->assertContains('', $actualXml, 'Exception trace is not found in XML.'); } diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php index 02cd70515eb9d..81235e335b8fa 100644 --- a/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php +++ b/app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php @@ -63,7 +63,7 @@ class AsynchronousRequestProcessor implements RequestProcessorInterface * @param RestResponse $response * @param InputParamsResolver $inputParamsResolver * @param MassSchedule $asyncBulkPublisher - * @param WebapiAsyncConfig $webapiAsyncConfig + * @param WebApiAsyncConfig $webapiAsyncConfig * @param DataObjectProcessor $dataObjectProcessor * @param AsyncResponseInterfaceFactory $asyncResponse * @param string $processorPath diff --git a/app/code/Magento/WebapiAsync/Model/BulkServiceConfig.php b/app/code/Magento/WebapiAsync/Model/BulkServiceConfig.php index 16f09ef9c5246..4abd8fa4d1439 100644 --- a/app/code/Magento/WebapiAsync/Model/BulkServiceConfig.php +++ b/app/code/Magento/WebapiAsync/Model/BulkServiceConfig.php @@ -10,7 +10,6 @@ use Magento\Framework\Serialize\SerializerInterface; use Magento\Webapi\Model\Cache\Type\Webapi as WebapiCache; -use Magento\WebapiAsync\Model\ServiceConfig\Converter; use Magento\Webapi\Model\Config\Converter as WebapiConverter; use Magento\Webapi\Model\Config; @@ -42,7 +41,7 @@ class BulkServiceConfig implements \Magento\Webapi\Model\ConfigInterface * Initialize dependencies. * * @param WebapiCache $cache - * @param Config $configReader + * @param Config $webapiConfig * @param SerializerInterface $serializer */ public function __construct( diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig.php index aec8f905cd034..4c085935090bd 100644 --- a/app/code/Magento/WebapiAsync/Model/ServiceConfig.php +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig.php @@ -20,7 +20,7 @@ */ class ServiceConfig { - const CACHE_ID = 'webapi_async_config'; + const CACHE_ID = 'webapi_async_service_config'; /** * @var WebapiCache @@ -71,7 +71,7 @@ public function getServices() if ($services && is_string($services)) { $this->services = $this->serializer->unserialize($services); } else { - $this->services = $this->configReader->read()[Converter::KEY_SERVICES] ?? []; + $this->services = $this->configReader->read(); $this->cache->save($this->serializer->serialize($this->services), self::CACHE_ID); } } diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php index 7b9e206aa6532..2c85796a3ab19 100644 --- a/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Converter.php @@ -20,8 +20,17 @@ class Converter implements \Magento\Framework\Config\ConverterInterface const KEY_METHOD = 'method'; const KEY_METHODS = 'methods'; const KEY_SYNCHRONOUS_INVOCATION_ONLY = 'synchronousInvocationOnly'; + const KEY_ROUTES = 'routes'; /**#@-*/ + private $allowedRouteMethods = [ + \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET, + \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST, + \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT, + \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE, + \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PATCH + ]; + /** * {@inheritdoc} * @SuppressWarnings(PHPMD.CyclomaticComplexity) @@ -44,6 +53,7 @@ public function convert($source) $this->initServiceMethodsKey($result, $serviceClass, $serviceMethod); $this->mergeSynchronousInvocationMethodsData($service, $result, $serviceClass, $serviceMethod); } + $result[self::KEY_ROUTES] = $this->convertRouteCustomizations($source); return $result; } @@ -158,4 +168,68 @@ private function isSynchronousInvocationOnlyTrue(\DOMElement $synchronousInvocat return filter_var($synchronousInvocationOnlyNode->nodeValue, FILTER_VALIDATE_BOOLEAN); } + + /** + * Convert and merge "route" nodes, which represent route customizations + * @param \DOMDocument $source + * @return array + */ + private function convertRouteCustomizations($source) + { + $customRoutes = []; + $routes = $source->getElementsByTagName('route'); + /** @var \DOMElement $route */ + foreach ($routes as $route) { + $routeUrl = $this->getRouteUrl($route); + $routeMethod = $this->getRouteMethod($route); + $routeAlias = $this->getRouteAlias($route); + if ($routeUrl && $routeMethod && $routeAlias) { + if (!isset($customRoutes[$routeAlias])) { + $customRoutes[$routeAlias] = []; + } + $customRoutes[$routeAlias][$routeMethod] = $routeUrl; + } + } + return $customRoutes; + } + + /** + * @param \DOMElement $route + * @return null|string + */ + private function getRouteUrl($route) + { + $url = $route->attributes->getNamedItem('url')->nodeValue; + return mb_strlen((string) $url) === 0 ? null : $url; + } + + /** + * @param \DOMElement $route + * @return null|string + */ + private function getRouteAlias($route) + { + $alias = $route->attributes->getNamedItem('alias')->nodeValue; + return mb_strlen((string) $alias) === 0 ? null : ltrim($alias, '/'); + } + + /** + * @param \DOMElement $route + * @return null|string + */ + private function getRouteMethod($route) + { + $method = $route->attributes->getNamedItem('method')->nodeValue; + $method = mb_strlen((string) $method) === 0 ? null : $method; + return ($this->validateRouteMethod($method)) ? $method : null; + } + + /** + * @param string $method + * @return bool + */ + private function validateRouteMethod($method) + { + return in_array($method, $this->allowedRouteMethods); + } } diff --git a/app/code/Magento/WebapiAsync/Model/ServiceConfig/Reader.php b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Reader.php index 95517463be4f5..b2d5c789286dc 100644 --- a/app/code/Magento/WebapiAsync/Model/ServiceConfig/Reader.php +++ b/app/code/Magento/WebapiAsync/Model/ServiceConfig/Reader.php @@ -20,6 +20,7 @@ class Reader extends \Magento\Framework\Config\Reader\Filesystem */ protected $_idAttributes = [ '/services/service' => ['class', 'method'], + '/services/route' => ['url', 'method'] ]; /** diff --git a/app/code/Magento/WebapiAsync/Plugin/ControllerRest.php b/app/code/Magento/WebapiAsync/Plugin/ControllerRest.php new file mode 100644 index 0000000000000..b3ba6af8bab60 --- /dev/null +++ b/app/code/Magento/WebapiAsync/Plugin/ControllerRest.php @@ -0,0 +1,65 @@ +serviceConfig = $serviceConfig; + $this->pathProcessor = $pathProcessor; + } + + /** + * Apply route customization. + * @param \Magento\Webapi\Controller\Rest $subject + * @param RequestInterface $request + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforeDispatch(\Magento\Webapi\Controller\Rest $subject, RequestInterface $request) + { + $routeCustomizations = $this->serviceConfig->getServices()[Converter::KEY_ROUTES] ?? []; + if ($routeCustomizations) { + $originPath = $request->getPathInfo(); + $requestMethod = $request->getMethod(); + $routePath = ltrim($this->pathProcessor->process($originPath), '/'); + if (array_key_exists($routePath, $routeCustomizations)) { + if (isset($routeCustomizations[$routePath][$requestMethod])) { + $path = ltrim($routeCustomizations[$routePath][$requestMethod], '/'); + $request->setPathInfo(str_replace($routePath, $path, $originPath)); + } + } + } + return [$request]; + } +} diff --git a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php index e91fe8b13aafd..c4e5b572b80f9 100644 --- a/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php +++ b/app/code/Magento/WebapiAsync/Plugin/ServiceMetadata.php @@ -129,7 +129,8 @@ private function getServiceVersions(string $serviceName) private function getSynchronousOnlyServiceMethods(\Magento\Webapi\Model\ServiceMetadata $serviceMetadata) { $synchronousOnlyServiceMethods = []; - foreach ($this->serviceConfig->getServices() as $service => $serviceData) { + $services = $this->serviceConfig->getServices()[Converter::KEY_SERVICES] ?? []; + foreach ($services as $service => $serviceData) { if (!isset($serviceData[Converter::KEY_METHODS])) { continue; } diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.php index cbe3b5522f196..43c6da9f6702b 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.php @@ -22,4 +22,9 @@ ], ], ], + 'routes' => [ + 'asyncProducts' => ['POST' => 'async/V1/products'], + 'asyncBulkCmsBlocks' => ['POST' => 'async/bulk/V1/cmsBlock'], + 'asyncCustomers' => ['POST' => 'async/V1/customers'] + ] ]; diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.xml b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.xml index e4ba6da62339c..be119c7da707d 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.xml +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Converter/webapi_async.xml @@ -16,4 +16,8 @@ + + + + diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async.php b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async.php index cbe3b5522f196..6938ec27c99b7 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async.php +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async.php @@ -22,4 +22,9 @@ ], ], ], + 'routes' => [ + 'asyncProducts' => ['POST' => 'async/bulk/V1/products'], + 'asyncBulkCmsPages' => ['POST' => 'async/bulk/V1/cmsPage'], + 'asyncCustomers' => ['POST' => 'async/V1/customers'] + ] ]; diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_1.xml b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_1.xml index 7f816f510ddb6..bd9895c7eef1e 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_1.xml +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_1.xml @@ -15,4 +15,7 @@ + + + diff --git a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_2.xml b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_2.xml index 7a5bebd8fe566..153e3344ca72b 100644 --- a/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_2.xml +++ b/app/code/Magento/WebapiAsync/Test/Unit/Model/ServiceConfig/_files/Reader/webapi_async_2.xml @@ -8,5 +8,5 @@ - + diff --git a/app/code/Magento/WebapiAsync/etc/di.xml b/app/code/Magento/WebapiAsync/etc/di.xml index b9cd7302b7350..83f1d6a78f227 100755 --- a/app/code/Magento/WebapiAsync/etc/di.xml +++ b/app/code/Magento/WebapiAsync/etc/di.xml @@ -42,4 +42,7 @@ Magento\WebapiAsync\Controller\Rest\AsynchronousSchemaRequestProcessor::BULK_PROCESSOR_PATH + + + diff --git a/app/code/Magento/WebapiAsync/etc/webapi_async.xml b/app/code/Magento/WebapiAsync/etc/webapi_async.xml new file mode 100644 index 0000000000000..109835acadce0 --- /dev/null +++ b/app/code/Magento/WebapiAsync/etc/webapi_async.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/code/Magento/WebapiAsync/etc/webapi_async.xsd b/app/code/Magento/WebapiAsync/etc/webapi_async.xsd index 468ebd96553b6..c41d9811f2d63 100644 --- a/app/code/Magento/WebapiAsync/etc/webapi_async.xsd +++ b/app/code/Magento/WebapiAsync/etc/webapi_async.xsd @@ -8,7 +8,14 @@ */ --> - + + + + + + + + @@ -18,10 +25,19 @@ - - - - + + + + + + + + + + + + + diff --git a/app/code/Magento/Weee/Model/Attribute/Backend/Weee/Tax.php b/app/code/Magento/Weee/Model/Attribute/Backend/Weee/Tax.php index 11b976a640b07..35835e6c5f63f 100644 --- a/app/code/Magento/Weee/Model/Attribute/Backend/Weee/Tax.php +++ b/app/code/Magento/Weee/Model/Attribute/Backend/Weee/Tax.php @@ -185,4 +185,12 @@ public function getTable() { return $this->_attributeTax->getTable('weee_tax'); } + + /** + * @inheritdoc + */ + public function getEntityIdField() + { + return $this->_attributeTax->getIdFieldName(); + } } diff --git a/app/code/Magento/Weee/Test/Unit/Model/Attribute/Backend/Weee/TaxTest.php b/app/code/Magento/Weee/Test/Unit/Model/Attribute/Backend/Weee/TaxTest.php index c264bbca83b78..7170969f5953e 100644 --- a/app/code/Magento/Weee/Test/Unit/Model/Attribute/Backend/Weee/TaxTest.php +++ b/app/code/Magento/Weee/Test/Unit/Model/Attribute/Backend/Weee/TaxTest.php @@ -269,4 +269,31 @@ public function testGetTable() $model->getTable(); } + + /** + * Test method GetEntityIdField. + * + * @return void + */ + public function testGetEntityIdField() : void + { + $attributeTaxMock = $this->getMockBuilder(\Magento\Weee\Model\ResourceModel\Attribute\Backend\Weee\Tax::class) + ->setMethods(['getIdFieldName']) + ->disableOriginalConstructor() + ->getMock(); + + $attributeTaxMock + ->expects($this->once()) + ->method('getIdFieldName') + ->willReturn(null); + + $model = $this->objectManager->getObject( + \Magento\Weee\Model\Attribute\Backend\Weee\Tax::class, + [ + 'attributeTax' => $attributeTaxMock, + ] + ); + + $model->getEntityIdField(); + } } diff --git a/app/code/Magento/Wishlist/CustomerData/Wishlist.php b/app/code/Magento/Wishlist/CustomerData/Wishlist.php index 85aff60ac6370..eeae07861e22d 100644 --- a/app/code/Magento/Wishlist/CustomerData/Wishlist.php +++ b/app/code/Magento/Wishlist/CustomerData/Wishlist.php @@ -149,6 +149,14 @@ protected function getItemData(\Magento\Wishlist\Model\Item $wishlistItem) */ protected function getImageData($product) { + /*Set variant product if it is configurable product. + It will show variant product image in sidebar instead of configurable product image.*/ + $simpleOption = $product->getCustomOption('simple_product'); + if ($simpleOption !== null) { + $optionProduct = $simpleOption->getProduct(); + $product = $optionProduct; + } + /** @var \Magento\Catalog\Helper\Image $helper */ $helper = $this->imageHelperFactory->create() ->init($product, 'wishlist_sidebar_block'); diff --git a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/lib/forms/_checkbox-radio.less b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/lib/forms/_checkbox-radio.less index 44b6a1568ef9b..82a6f7b2f19bd 100644 --- a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/lib/forms/_checkbox-radio.less +++ b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/lib/forms/_checkbox-radio.less @@ -87,7 +87,7 @@ .form-el-checkbox { &:checked { + .form-label { - &::before { + &:before { content: @checkbox-icon__content; font-family: @icons__font-family; } diff --git a/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less b/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less index 2e8f06c091265..283054e015fc5 100644 --- a/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less +++ b/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less @@ -22,8 +22,8 @@ vertical-align: middle; width: @component-indicator__size; - &::before, - &::after { + &:before, + &:after { background: @color-white; display: block; opacity: 0; @@ -32,7 +32,7 @@ visibility: hidden; } - &::before { + &:before { border: 1px solid @color-gray68; border-radius: 1px; box-shadow: 0 0 2px rgba(0,0,0,.4); @@ -43,7 +43,7 @@ padding: 4px 5px; } - &::after { + &:after { border-color: darken(@color-gray68, 8); border-style: solid; border-width: 1px 0 0 1px; @@ -56,8 +56,8 @@ } &:hover { - &::before, - &::after { + &:before, + &:after { opacity: 1; transition: opacity .2s linear; visibility: visible; @@ -115,7 +115,7 @@ &._tooltip { background: transparent; - margin: 0px 0px 8px 5px; + margin: 0 0 8px 5px; a { width: 21px; diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_file-uploader.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_file-uploader.less index 959b37de5a5a1..79e3975a41bc6 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/components/_file-uploader.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_file-uploader.less @@ -66,6 +66,7 @@ opacity: 0; overflow: hidden; position: absolute; + visibility: hidden; width: 0; &:focus { @@ -241,7 +242,7 @@ } } -// Placeholder for multiple uploader +// Placeholder for multiple uploader .file-uploader-placeholder { &.placeholder-document { .lib-icon-font( diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less index 2dd8463308a2c..08a9b61977922 100644 --- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less @@ -507,6 +507,16 @@ } } + // + // Category page 1 column layout + // --------------------------------------------- + + .catalog-category-view.page-layout-1column { + .column.main { + min-height: inherit; + } + } + } // diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_authentication.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_authentication.less index e1e23a9ffbb15..3fdd20e34e09a 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_authentication.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_authentication.less @@ -25,6 +25,7 @@ padding: @block-auth__dropdown__padding; } } + .authentication-wrapper { float: right; margin-top: -1.5*@indent__xl; @@ -94,7 +95,7 @@ padding-top: @indent__xl; position: relative; - &::before { + &:before { .lib-css(height, @block-auth__or-label__size); .lib-css(line-height, @block-auth__or-label__size - 2px); .lib-css(margin, -(@block-auth__or-label__size/2 + 1px) 0 0 -(@block-auth__or-label__size / 2)); @@ -212,7 +213,7 @@ margin: 0; padding: @indent__s 0 0 @indent__xl; - &::before { + &:before { left: 0; top: 50%; } diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_estimated-total.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_estimated-total.less index 86df8d870552b..85c65bd0ff2d7 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_estimated-total.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_estimated-total.less @@ -35,7 +35,11 @@ .action { &.showcart { &:before { - .lib-css(color, @primary__color); + .lib-css(color, @button__color); + } + + &:hover:before { + .lib-css(color, @button__hover__color); } } } diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payment-options.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payment-options.less index 4e1156949de3a..3ce46a73a11c4 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payment-options.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payment-options.less @@ -198,6 +198,7 @@ .payment-option-title { .lib-css(padding-left, @checkout-payment-option-content__padding__xl); } + .payment-option-content { .payment-option-inner { + .actions-toolbar { diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less index e7f0259fc9ce3..0a463a95e3182 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less @@ -188,6 +188,7 @@ } } } + .row-error { td { border-top: none; @@ -285,6 +286,7 @@ .lib-css(max-width, @checkout-shipping-address__max-width); } } + .table-checkout-shipping-method { width: auto; } @@ -324,6 +326,7 @@ } } } + .table-checkout-shipping-method { min-width: 500px; } diff --git a/app/design/frontend/Magento/blank/Magento_GiftRegistry/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_GiftRegistry/web/css/source/_module.less index d05bcec38cbed..03a474012cb0c 100644 --- a/app/design/frontend/Magento/blank/Magento_GiftRegistry/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_GiftRegistry/web/css/source/_module.less @@ -15,6 +15,7 @@ .actions-toolbar:not(:last-child) { margin-bottom: @indent__xl; } + .fieldset { .nested { .field:not(.choice) { diff --git a/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/_module.less index 1e5769f3d7396..66dbb30cb6712 100644 --- a/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/_module.less @@ -9,7 +9,8 @@ & when (@media-common = true) { .multicheckout { - &.results, &.success { + &.results, + &.success { h3 { font-size: 1.6rem; margin-bottom: @indent__base; @@ -33,15 +34,18 @@ .shipping-list { .shipping-item { - margin-left:84px; + margin-left: 84px; } + .shipping-label { font-weight: @font-weight__bold; margin-right: @indent__s; } + .shipping-address { font-weight: @font-weight__regular; } + .error-block { color: @color-red10; @@ -49,6 +53,7 @@ font-weight: @font-weight__bold; margin-right: @indent__s; } + .error-description { font-weight: @font-weight__regular; } @@ -62,10 +67,11 @@ .shipping-list { .order-id { - float:left; + float: left; } + .shipping-item { - margin-left:100px; + margin-left: 100px; } } } diff --git a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less index 228c6947c938b..501a1d2918d6a 100644 --- a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less @@ -747,6 +747,16 @@ } } } + + // + // Category page 1 column layout + // --------------------------------------------- + + .catalog-category-view.page-layout-1column { + .column.main { + min-height: inherit; + } + } } // diff --git a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less index a8778da50f70b..d0382d34d39fc 100644 --- a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less +++ b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less @@ -167,11 +167,11 @@ .column.main { .product { &-items { - margin-left: -@indent__base; + margin-left: 0; } &-item { - padding-left: @indent__base; + padding-left: 0; } } } diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_shipping.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_shipping.less index 512751df1cb35..d0ce87beb6ad3 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_shipping.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_shipping.less @@ -296,6 +296,7 @@ } } } + .opc-wrapper { .form-login, .form-shipping-address { @@ -307,6 +308,7 @@ padding-bottom: @indent__base; } } + .table-checkout-shipping-method { width: auto; } @@ -346,6 +348,7 @@ } } } + .table-checkout-shipping-method { min-width: 500px; } diff --git a/app/design/frontend/Magento/luma/Magento_InstantPurchase/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_InstantPurchase/web/css/source/_module.less index 9877f6bbcea23..9ab5148a87264 100644 --- a/app/design/frontend/Magento/luma/Magento_InstantPurchase/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_InstantPurchase/web/css/source/_module.less @@ -1,16 +1,21 @@ +// /** +// * Copyright © Magento, Inc. All rights reserved. +// * See COPYING.txt for license details. +// */ + & when (@media-common = true) { - .box-tocart { - .action.instant-purchase { - &:extend(.abs-button-l all); - &:extend(.abs-button-responsive all); + .box-tocart { + .action.instant-purchase { + &:extend(.abs-button-l all); + &:extend(.abs-button-responsive all); - &:not(:last-child) { - margin-bottom: 15px; - } + &:not(:last-child) { + margin-bottom: 15px; + } - vertical-align: top; + vertical-align: top; + } } - } } // @@ -18,11 +23,11 @@ // _____________________________________________ .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) { - .box-tocart { - .action.instant-purchase { - margin-bottom: 0; - margin-right: 1%; - width: 49%; + .box-tocart { + .action.instant-purchase { + margin-bottom: 0; + margin-right: 1%; + width: 49%; + } } - } } diff --git a/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less index 03ff1fb09a3e4..7662c60734a1b 100644 --- a/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less @@ -8,285 +8,291 @@ // _____________________________________________ & when (@media-common = true) { - .multicheckout { - &.results, &.success { - h3 { - font-size: 1.6rem; - margin-bottom: @indent__base; - margin-top: @indent__l; - a { - color: @text__color; - &:hover { - text-decoration: none; - } - } - } - - ul.orders-list { - list-style: none; - padding-left: 0; - } - - .orders-list { - margin-top: @indent__m; - padding-left: @indent__base - 4px; - - .shipping-list { - .shipping-item { - margin-left:84px; - } - .shipping-label { - font-weight: @font-weight__bold; - margin-right: @indent__s; - } - .shipping-address { - font-weight: @font-weight__regular; - } - .error-block { - color: @color-red10; - .error-label { - font-weight: @font-weight__bold; - margin-right: @indent__s; + .multicheckout { + &.results, + &.success { + h3 { + font-size: 1.6rem; + margin-bottom: @indent__base; + margin-top: @indent__l; + a { + color: @text__color; + &:hover { + text-decoration: none; + } } - .error-description { - font-weight: @font-weight__regular; + } + + ul.orders-list { + list-style: none; + padding-left: 0; + } + + .orders-list { + margin-top: @indent__m; + padding-left: @indent__base - 4px; + + .shipping-list { + .shipping-item { + margin-left: 84px; + } + + .shipping-label { + font-weight: @font-weight__bold; + margin-right: @indent__s; + } + + .shipping-address { + font-weight: @font-weight__regular; + } + + .error-block { + color: @color-red10; + + .error-label { + font-weight: @font-weight__bold; + margin-right: @indent__s; + } + + .error-description { + font-weight: @font-weight__regular; + } + } } - } } - } - .orders-succeed { - .orders-list { - margin-top: 0; + .orders-succeed { + .orders-list { + margin-top: 0; + + .shipping-list { + .order-id { + float: left; + } + .shipping-item { + margin-left: 100px; + } + } + } + } + } - .shipping-list { - .order-id { - float:left; - } - .shipping-item { - margin-left:100px; - } + .title { + margin-bottom: @indent__l; + + strong { + font-weight: @font-weight__regular; } - } } - } - .title { - margin-bottom: @indent__l; + .table-wrapper { + margin-bottom: 0; - strong { - font-weight: @font-weight__regular; - } - } + .action.delete { + display: inline-block; + } + + .col { + .qty { + display: inline-block; + + .input-text { + &:extend(.abs-input-qty all); + } + } - .table-wrapper { - margin-bottom: 0; + .label { + &:extend(.abs-visually-hidden all); + } - .action.delete { - display: inline-block; - } + &.item { + .action.edit { + font-weight: @font-weight__regular; + margin-left: @indent__s; + } + } + } - .col { - .qty { - display: inline-block; + .cart-price { + &:extend(.abs-checkout-cart-price all); + } - .input-text { - &:extend(.abs-input-qty all); - } + .product-item-name { + &:extend(.abs-checkout-product-name all); + } } - .label { - &:extend(.abs-visually-hidden all); + &:not(.address) { + .table-wrapper { + .product-item-name { + margin: 0; + } + } } - &.item { - .action.edit { - font-weight: @font-weight__regular; - margin-left: @indent__s; - } + > .actions-toolbar { + margin-top: @indent__xl; } - } - .cart-price { - &:extend(.abs-checkout-cart-price all); - } + .actions-toolbar { + > .secondary { + display: block; - .product-item-name { - &:extend(.abs-checkout-product-name all); - } - } + .action { + margin-bottom: @indent__m; - &:not(.address) { - .table-wrapper { - .product-item-name { - margin: 0; - } - } - } + &.back { + display: block; + margin-left: 0; + } + } + } - > .actions-toolbar { - margin-top: @indent__xl; - } + > .primary { + margin-right: @indent__s; + } + } - .actions-toolbar { - > .secondary { - display: block; + .action.primary { + &:extend(.abs-button-l all); + } - .action { - margin-bottom: @indent__m; + .item-options { + margin: @indent__s 0 0; - &.back { - display: block; - margin-left: 0; - } + &:extend(.abs-product-options-list all); + &:extend(.abs-add-clearfix all); } - } - > .primary { - margin-right: @indent__s; - } - } + &:extend(.abs-account-blocks all); - .action.primary { - &:extend(.abs-button-l all); - } + .block { + &:extend(.abs-add-clearfix all); - .item-options { - margin: @indent__s 0 0; - - &:extend(.abs-product-options-list all); - &:extend(.abs-add-clearfix all); - } + .methods-shipping { + .item-content { + .fieldset { + > .legend { + &:extend(.abs-visually-hidden all); + } - &:extend(.abs-account-blocks all); + > .legend + br { + &:extend(.abs-no-display all); + } - .block { - &:extend(.abs-add-clearfix all); + > .field { + &:before { + display: none; + } - .methods-shipping { - .item-content { - .fieldset { - > .legend { - &:extend(.abs-visually-hidden all); + .control { + display: inline-block; + } + } + } + } } + } - > .legend + br { - &:extend(.abs-no-display all); - } + .block-title, + .block-content .title { + &:extend(.abs-account-title all); + border-bottom: @border-width__base solid @border-color__base; + padding-bottom: @indent__s; - > .field { - &:before { - display: none; - } + strong { + font-weight: @font-weight__regular; - .control { - display: inline-block; - } + span { + .lib-css(color, @primary__color__light); + } } - } } - } - } - - .block-title, - .block-content .title { - &:extend(.abs-account-title all); - border-bottom: @border-width__base solid @border-color__base; - padding-bottom: @indent__s; - - strong { - font-weight: @font-weight__regular; - span { - .lib-css(color, @primary__color__light); + .block-content { + &:extend(.abs-add-clearfix all); + .title { + border-bottom: none; + padding-bottom: 0; + } } - } - } - .block-content { - &:extend(.abs-add-clearfix all); - .title { - border-bottom: none; - padding-bottom: 0; - } - } + &.order-review { + .block-title > strong { + .lib-font-size(24); + } - &.order-review { - .block-title > strong { - .lib-font-size(24); - } + .block-shipping { + .block-content:not(:last-child) { + margin-bottom: @indent__xl; + } + } - .block-shipping { - .block-content:not(:last-child) { - margin-bottom: @indent__xl; + .error-description { + color: @color-red10; + font-weight: @font-weight__regular; + margin-bottom: @indent__s; + margin-top: -@indent__s; + } } - } - .error-description { - color: @color-red10; - font-weight: @font-weight__regular; - margin-bottom: @indent__s; - margin-top: -@indent__s; - } - } - - .box-title { - span { - margin-right: @indent__s; - } + .box-title { + span { + margin-right: @indent__s; + } - > .action { - margin: 0; - } - } + > .action { + margin: 0; + } + } - .box-shipping-method { - .price { - font-weight: @font-weight__bold; - } - } + .box-shipping-method { + .price { + font-weight: @font-weight__bold; + } + } - .box-billing-method { - .fieldset { - margin: 0; + .box-billing-method { + .fieldset { + margin: 0; - .legend.box-title { - margin: 0 0 @indent__xs; + .legend.box-title { + margin: 0 0 @indent__xs; + } + } } - } - } - .hidden { - &:extend(.abs-no-display all); - } + .hidden { + &:extend(.abs-no-display all); + } - .checkout-review .grand.totals { - .lib-font-size(@font-size__xl); - margin-bottom: @indent__xl; + .checkout-review .grand.totals { + .lib-font-size(@font-size__xl); + margin-bottom: @indent__xl; - .mark { - font-weight: @font-weight__regular; - } + .mark { + font-weight: @font-weight__regular; + } + } } - } - [class^='multishipping-'] { - .nav-sections, - .nav-toggle { - &:extend(.abs-no-display all); - } + [class^='multishipping-'] { + .nav-sections, + .nav-toggle { + &:extend(.abs-no-display all); + } - .logo { - margin-left: 0; + .logo { + margin-left: 0; + } } - } - .multishipping-checkout-success { - .nav-sections { - display: block; + .multishipping-checkout-success { + .nav-sections { + display: block; + } } - } } // @@ -294,200 +300,200 @@ // _____________________________________________ .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) { - .multicheckout { - .data.table { - .address { - &:before { - margin-bottom: @indent__xs; + .multicheckout { + .data.table { + .address { + &:before { + margin-bottom: @indent__xs; + } + } } - } - } - - .product-item-name, - .price-including-tax, - .price-excluding-tax { - display: inline-block; - } - .block-content .box { - &:not(:last-child) { - margin-bottom: @indent__xl; - } + .product-item-name, + .price-including-tax, + .price-excluding-tax { + display: inline-block; + } - &:last-child { - margin-bottom: 0; - } - } + .block-content .box { + &:not(:last-child) { + margin-bottom: @indent__xl; + } - &.order-review { - .box-items { - .data.table { - thead { - display: block; + &:last-child { + margin-bottom: 0; + } + } - tr { - display: block; + &.order-review { + .box-items { + .data.table { + thead { + display: block; + + tr { + display: block; + } + + .col.item { + display: block; + padding: 0; + } + } + } } - .col.item { - display: block; - padding: 0; + .data.table { + &:extend(.abs-checkout-order-review all); } - } } - } - - .data.table { - &:extend(.abs-checkout-order-review all); - } - } - .actions-toolbar { - .action { - margin-bottom: @indent__m; - } + .actions-toolbar { + .action { + margin-bottom: @indent__m; + } - > .primary { - margin-bottom: @indent__m; - margin-right: 0; - } + > .primary { + margin-bottom: @indent__m; + margin-right: 0; + } + } } - } } .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__s) { - .multicheckout { - .actions-toolbar { - .column:not(.sidebar-main) & { - &:extend(.abs-reset-left-margin-desktop-s all); - } + .multicheckout { + .actions-toolbar { + .column:not(.sidebar-main) & { + &:extend(.abs-reset-left-margin-desktop-s all); + } - .secondary { - float: none; - margin-top: 11px; - text-align: right; + .secondary { + float: none; + margin-top: 11px; + text-align: right; - .action { - margin-left: @indent__s; + .action { + margin-left: @indent__s; - &.back { - display: block; - float: left; - } + &.back { + display: block; + float: left; + } + } + } } - } - } - - .item-options { - margin: @indent__base 0 0; - } - - .block-content .box { - margin-bottom: 0; - } - .block-shipping { - .box { - &:extend(.abs-add-box-sizing-desktop-s all); - float: left; - width: 25%; - } + .item-options { + margin: @indent__base 0 0; + } - .box-shipping-method { - padding-left: @indent__m; - padding-right: @indent__m; - width: 50%; + .block-content .box { + margin-bottom: 0; + } - .fieldset { - .legend { - &:extend(.abs-reset-left-margin-desktop-s all); - } + .block-shipping { + .box { + &:extend(.abs-add-box-sizing-desktop-s all); + float: left; + width: 25%; + } - .field { - &:before { - display: none; + .box-shipping-method { + padding-left: @indent__m; + padding-right: @indent__m; + width: 50%; + + .fieldset { + .legend { + &:extend(.abs-reset-left-margin-desktop-s all); + } + + .field { + &:before { + display: none; + } + } + } } - } } - } - } - .block-billing { - &:extend(.abs-add-clearfix-desktop-s all); - .box-billing-address { - &:extend(.abs-add-box-sizing-desktop-s all); - float: left; - width: 25%; - } - - .box-billing-method { - &:extend(.abs-add-box-sizing-desktop-s all); - float: left; - padding-left: @indent__m; - width: 50%; - } - } + .block-billing { + &:extend(.abs-add-clearfix-desktop-s all); + .box-billing-address { + &:extend(.abs-add-box-sizing-desktop-s all); + float: left; + width: 25%; + } - &.form.address { - .table-wrapper { - .applicable { - margin: 7px 0 0; + .box-billing-method { + &:extend(.abs-add-box-sizing-desktop-s all); + float: left; + padding-left: @indent__m; + width: 50%; + } } - } - } - &.order-review { - .box-items { - clear: left; - float: none; - padding-top: @indent__xl; - width: auto; - } - - .col.item { - width: 75%; - } - } + &.form.address { + .table-wrapper { + .applicable { + margin: 7px 0 0; + } + } + } - // Payment methods - .methods-payment { - .item-content > .fieldset { - width: auto; + &.order-review { + .box-items { + clear: left; + float: none; + padding-top: @indent__xl; + width: auto; + } - .field { - &.cvv { - display: inline-block; - width: auto; - } + .col.item { + width: 75%; + } } - } - .fieldset > .field:not(.choice) { - > .label { - float: none; - margin-bottom: 8px; - text-align: left; - width: auto; - } + // Payment methods + .methods-payment { + .item-content > .fieldset { + width: auto; + + .field { + &.cvv { + display: inline-block; + width: auto; + } + } + } + + .fieldset > .field:not(.choice) { + > .label { + float: none; + margin-bottom: 8px; + text-align: left; + width: auto; + } - &:not(.cvv) { - .control { - width: 100%; - } + &:not(.cvv) { + .control { + width: 100%; + } + } + } } - } } - } } .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { - .multishipping-checkout-success { - .nav-toggle { - display: block; - } + .multishipping-checkout-success { + .nav-toggle { + display: block; + } - .logo { - margin-left: @indent__xl; + .logo { + margin-left: @indent__xl; + } } - } } diff --git a/app/design/frontend/Magento/luma/web/css/source/_actions-toolbar.less b/app/design/frontend/Magento/luma/web/css/source/_actions-toolbar.less index 096b93675a92c..d81d0a8388a78 100644 --- a/app/design/frontend/Magento/luma/web/css/source/_actions-toolbar.less +++ b/app/design/frontend/Magento/luma/web/css/source/_actions-toolbar.less @@ -22,10 +22,6 @@ &:last-child { margin-bottom: 0; } - - &.primary { - // &:extend(.abs-button-l all); - } } &:last-child { diff --git a/app/etc/di.xml b/app/etc/di.xml index 6e3dabaa0751f..76f9e8f590f1c 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -249,9 +249,15 @@ Magento\Framework\Logger\Handler\System Magento\Framework\Logger\Handler\Debug + Magento\Framework\Logger\Handler\Syslog + + + Magento + + Magento\Framework\Model\ActionValidator\RemoveAction\Proxy diff --git a/bin/UpgradeScripts/pre_composer_update_2.3.php b/bin/UpgradeScripts/pre_composer_update_2.3.php deleted file mode 100644 index 1658c8a4e6681..0000000000000 --- a/bin/UpgradeScripts/pre_composer_update_2.3.php +++ /dev/null @@ -1,251 +0,0 @@ -#!/usr/bin/php -" [--composer=] - [--edition=] [--version=] [--repo=] - [--help] - -Required: - --root="" - Path to the Magento installation root directory - -Optional: - --composer="" - Path to the composer executable - - Default: The composer found in PATH - - --edition= - The Magento edition to upgrade to. Open Source = 'community', Commerce = 'enterprise' - - Default: The edition currently required in composer.json - - --version= - The Magento version to upgrade to - - Default: The value for the "version" field in composer.json - - --repo= - The Magento composer repository to pull new packages from - - Default: The Magento repository configured in composer.json - - --help - Display this message -SYNOPSIS -); - - -$opts = getopt('', [ - 'root:', - 'composer:', - 'edition:', - 'version:', - 'repo:', - 'help' -]); - -if (isset($opts['help'])) { - echo SYNOPSIS . PHP_EOL; - exit(0); -} - -try { - if (empty($opts['root'])) { - throw new BadMethodCallException("Magento root must be given with '--root'" . PHP_EOL . PHP_EOL . SYNOPSIS); - } - - $rootDir = $opts['root']; - if (!is_dir($rootDir)) { - throw new InvalidArgumentException("Magento root directory '$rootDir' does not exist"); - } - - $cmd = (!empty($opts['composer']) ? $opts['composer'] : 'composer') . " --working-dir='$rootDir'"; - $jsonData = json_decode(file_get_contents("$rootDir/composer.json"), true); - - $version = !empty($opts['version']) ? $opts['version'] : $jsonData['version']; - if (empty($version)) { - throw new InvalidArgumentException('Value not found for "version" field in composer.json'); - } - - if (!empty($opts['edition'])) { - $edition = $opts['edition']; - } - else { - $editionRegex = '|^magento/product\-(?[a-z]+)\-edition$|'; - - foreach (array_keys($jsonData["require"]) as $requiredPackage) { - if (preg_match($editionRegex, $requiredPackage, $matches)) { - $edition = $matches['edition']; - break; - } - } - if (empty($edition)) { - throw new InvalidArgumentException('No valid Magento edition found in composer.json requirements'); - } - } - - echo "Backing up $rootDir/composer.json" . PHP_EOL; - copy("$rootDir/composer.json", "$rootDir/composer.json.bak"); - - echo "Updating Magento product requirement to magento/product-$edition-edition=$version" . PHP_EOL; - if ($edition == "enterprise") { - execVerbose("$cmd remove --verbose magento/product-community-edition --no-update"); - } - execVerbose("$cmd require --verbose magento/product-$edition-edition=$version --no-update"); - - echo 'Updating "require-dev" section of composer.json' . PHP_EOL; - execVerbose("$cmd require --dev --verbose " . - "phpunit/phpunit:~6.2.0 " . - "friendsofphp/php-cs-fixer:~2.10.1 " . - "lusitanian/oauth:~0.8.10 " . - "pdepend/pdepend:2.5.2 " . - "sebastian/phpcpd:~3.0.0 " . - "squizlabs/php_codesniffer:3.2.2 --no-update"); - - execVerbose("$cmd remove --dev --verbose sjparkinson/static-review fabpot/php-cs-fixer --no-update"); - - echo 'Adding "Zend\\\\Mvc\\\\Controller\\\\": "setup/src/Zend/Mvc/Controller/" to "autoload":"psr-4"' . PHP_EOL; - $jsonData = json_decode(file_get_contents("$rootDir/composer.json"), true); - $jsonData["autoload"]["psr-4"]["Zend\\Mvc\\Controller\\"] = "setup/src/Zend/Mvc/Controller/"; - - $jsonData["version"] = $version; - file_put_contents("$rootDir/composer.json", json_encode($jsonData, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT)); - - if (file_exists("$rootDir/update")) { - echo "Replacing Magento/Updater" . PHP_EOL; - - $mageUrls = []; - if (isset($opts['repo'])) { - $mageUrls[] = $opts['repo']; - } - else { - $composerUrls = array_map(function ($r) { return $r["url"]; }, - array_filter($jsonData['repositories']), function ($r) { return $r["type"] == "composer"; }); - $mageUrls = array_filter($composerUrls, function($u) { return strpos($u, ".mage") !== false; }); - - if (count($mageUrls) == 0) { - throw new InvalidArgumentException('No Magento composer repository urls found in composer.json'); - } - } - - echo "Backing up $rootDir/update" . PHP_EOL; - rename("$rootDir/update", "$rootDir/update.bak"); - $newPackage = "magento/project-$edition-edition=$version"; - foreach ($mageUrls as $repoUrl) { - try { - deleteFilepath("$rootDir/temp_update"); - execVerbose("$cmd create-project --repository=$repoUrl $newPackage $rootDir/temp_update --no-install"); - rename("$rootDir/temp_update/update", "$rootDir/update"); - echo "Upgraded Magento/Updater from magento/project-$edition-edition $version on $repoUrl" . PHP_EOL; - unset($exception); - break; - } - catch (Exception $e) { - echo "Failed to find Magento package on $repoUrl" . PHP_EOL; - $exception = $e; - } - } - deleteFilepath("$rootDir/temp_update"); - - if (isset($exception)) { - throw $exception; - } - } -} catch (Exception $e) { - if ($e->getPrevious()) { - $message = (string)$e->getPrevious(); - } else { - $message = $e->getMessage(); - } - - try { - error_log($message . PHP_EOL . PHP_EOL . "Error encountered; resetting backups" . PHP_EOL); - if (file_exists("$rootDir/update.bak")) { - deleteFilepath("$rootDir/update_temp"); - deleteFilepath("$rootDir/update"); - rename("$rootDir/update.bak", "$rootDir/update"); - } - - if (file_exists("$rootDir/composer.json.bak")) { - deleteFilepath("$rootDir/composer.json"); - rename("$rootDir/composer.json.bak", "$rootDir/composer.json"); - } - } - catch (Exception $e) { - error_log($e->getMessage() . PHP_EOL); - } - - exit($e->getCode() == 0 ? 1 : $e->getCode()); -} - -/** - * Execute a command with automatic escaping of arguments - * - * @param string $command - * @return array - * @throws Exception - */ -function execVerbose($command) -{ - $args = func_get_args(); - $args = array_map('escapeshellarg', $args); - $args[0] = $command; - $command = call_user_func_array('sprintf', $args); - echo $command . PHP_EOL; - exec($command . " 2>&1", $output, $exitCode); - $outputString = join(PHP_EOL, $output); - if (0 !== $exitCode) { - throw new Exception($outputString, $exitCode); - } - echo $outputString . PHP_EOL; - return $output; -} - -/** - * Deletes a file or a directory and all its contents - * - * @param string $path - * @throws Exception - */ -function deleteFilepath($path) { - if (!file_exists($path)) { - return; - } - if (is_dir($path)) { - $files = array_diff(scandir($path), array('..', '.')); - foreach ($files as $file) { - deleteFilepath("$path/$file"); - } - rmdir($path); - } - else { - unlink($path); - } - if (file_exists($path)) { - throw new Exception("Failed to delete $path"); - } -} diff --git a/dev/tests/acceptance/tests/_data/LargerThan2MB.jpg b/dev/tests/acceptance/tests/_data/LargerThan2MB.jpg new file mode 100644 index 0000000000000..eb049be8baf1a Binary files /dev/null and b/dev/tests/acceptance/tests/_data/LargerThan2MB.jpg differ diff --git a/dev/tests/acceptance/tests/_data/adobe-base.jpg b/dev/tests/acceptance/tests/_data/adobe-base.jpg new file mode 100644 index 0000000000000..0b8fdef3cf50e Binary files /dev/null and b/dev/tests/acceptance/tests/_data/adobe-base.jpg differ diff --git a/dev/tests/acceptance/tests/_data/adobe-small.jpg b/dev/tests/acceptance/tests/_data/adobe-small.jpg new file mode 100644 index 0000000000000..6b9f44a16d91f Binary files /dev/null and b/dev/tests/acceptance/tests/_data/adobe-small.jpg differ diff --git a/dev/tests/acceptance/tests/_data/adobe-thumb.jpg b/dev/tests/acceptance/tests/_data/adobe-thumb.jpg new file mode 100644 index 0000000000000..31710b8e17ec6 Binary files /dev/null and b/dev/tests/acceptance/tests/_data/adobe-thumb.jpg differ diff --git a/dev/tests/acceptance/tests/_data/bmp.bmp b/dev/tests/acceptance/tests/_data/bmp.bmp new file mode 100755 index 0000000000000..285137a9e53a6 Binary files /dev/null and b/dev/tests/acceptance/tests/_data/bmp.bmp differ diff --git a/dev/tests/acceptance/tests/_data/empty.jpg b/dev/tests/acceptance/tests/_data/empty.jpg new file mode 100755 index 0000000000000..e69de29bb2d1d diff --git a/dev/tests/acceptance/tests/_data/gif.gif b/dev/tests/acceptance/tests/_data/gif.gif new file mode 100755 index 0000000000000..0b082504ab982 Binary files /dev/null and b/dev/tests/acceptance/tests/_data/gif.gif differ diff --git a/dev/tests/acceptance/tests/_data/ico.ico b/dev/tests/acceptance/tests/_data/ico.ico new file mode 100755 index 0000000000000..9ed7740904012 Binary files /dev/null and b/dev/tests/acceptance/tests/_data/ico.ico differ diff --git a/dev/tests/acceptance/tests/_data/jpg.jpg b/dev/tests/acceptance/tests/_data/jpg.jpg new file mode 100755 index 0000000000000..609bbb4827ab0 Binary files /dev/null and b/dev/tests/acceptance/tests/_data/jpg.jpg differ diff --git a/dev/tests/acceptance/tests/_data/large.jpg b/dev/tests/acceptance/tests/_data/large.jpg new file mode 100755 index 0000000000000..bb0bf4079e5eb Binary files /dev/null and b/dev/tests/acceptance/tests/_data/large.jpg differ diff --git a/dev/tests/acceptance/tests/_data/medium.jpg b/dev/tests/acceptance/tests/_data/medium.jpg new file mode 100755 index 0000000000000..90fe0aa0fb798 Binary files /dev/null and b/dev/tests/acceptance/tests/_data/medium.jpg differ diff --git a/dev/tests/acceptance/tests/_data/png.png b/dev/tests/acceptance/tests/_data/png.png new file mode 100755 index 0000000000000..c83255dcf558d Binary files /dev/null and b/dev/tests/acceptance/tests/_data/png.png differ diff --git a/dev/tests/acceptance/tests/_data/small.jpg b/dev/tests/acceptance/tests/_data/small.jpg new file mode 100755 index 0000000000000..0f69f526b5f11 Binary files /dev/null and b/dev/tests/acceptance/tests/_data/small.jpg differ diff --git a/dev/tests/acceptance/tests/_data/svg.svg b/dev/tests/acceptance/tests/_data/svg.svg new file mode 100755 index 0000000000000..a0f85579e39a5 --- /dev/null +++ b/dev/tests/acceptance/tests/_data/svg.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/dev/tests/acceptance/tests/_data/test-IMAGE_123,456.789.jpg b/dev/tests/acceptance/tests/_data/test-IMAGE_123,456.789.jpg new file mode 100644 index 0000000000000..c377daf8fb0b3 Binary files /dev/null and b/dev/tests/acceptance/tests/_data/test-IMAGE_123,456.789.jpg differ diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/SecondaryGridActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/SecondaryGridActionGroup.xml new file mode 100644 index 0000000000000..7c2c1c3c5702b --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/SecondaryGridActionGroup.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridTableSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridTableSection.xml new file mode 100644 index 0000000000000..3d96a48ac79b5 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminGridTableSection.xml @@ -0,0 +1,14 @@ + + + + +
+ +
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminMainActionsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminMainActionsSection.xml index 3097a6962a064..26c37fee8c12a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminMainActionsSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminMainActionsSection.xml @@ -9,5 +9,7 @@
+ +
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminSecondaryGridSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminSecondaryGridSection.xml new file mode 100644 index 0000000000000..a3268630567ad --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Section/AdminSecondaryGridSection.xml @@ -0,0 +1,17 @@ + + + + +
+ + + + +
+
diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Test/AdminLoginTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Test/AdminLoginTest.xml index 9387b8da659ef..3d0f6d5dfcea9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Test/AdminLoginTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/Test/AdminLoginTest.xml @@ -10,10 +10,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - + - - <description value="You should be able to log into the Magento Admin backend."/> + <title value="Admin should be able to log into the Magento Admin backend"/> + <description value="Admin should be able to log into the Magento Admin backend"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-71572"/> <group value="example"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/AdminClearFiltersActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/AdminClearFiltersActionGroup.xml new file mode 100644 index 0000000000000..cac724588937a --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/AdminClearFiltersActionGroup.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminClearFiltersActionGroup"> + <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage"/> + <waitForPageLoad stepKey="WaitForPageToLoad"/> + <conditionalClick selector="{{AdminProductFiltersSection.filtersClear}}" dependentSelector="{{AdminProductFiltersSection.filtersClear}}" visible="true" stepKey="ClickOnButtonToRemoveFiltersIfPresent"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/BundleProductFilterActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/BundleProductFilterActionGroup.xml new file mode 100644 index 0000000000000..cb0e9558976f5 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/BundleProductFilterActionGroup.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="BundleProductFilter"> + <!--Setting filter--> + <!--Prereq: go to admin product catalog page--> + <click selector="{{AdminProductFiltersSection.filter}}" stepKey="ClickOnFilter"/> + <click selector="{{AdminProductFiltersSection.typeDropDown}}" stepKey="ClickOnTypeDropDown"/> + <click selector="{{AdminProductFiltersSection.bundleOption}}" stepKey="ClickOnBundleOption"/> + <click selector="{{AdminProductFiltersSection.applyFilters}}" stepKey="ClickOnApplyFilters"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/CreateBundleProductActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/CreateBundleProductActionGroup.xml new file mode 100644 index 0000000000000..fa44b7df150e4 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/CreateBundleProductActionGroup.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="CreateBasicBundleProduct"> + <!--Prereq: Go to bundle product creation page--> + <!--Product name and SKU--> + <fillField selector="{{AdminProductFormBundleSection.productName}}" userInput="{{BundleProduct.name}}" stepKey="fillProductName"/> + <fillField selector="{{AdminProductFormBundleSection.productSku}}" userInput="{{BundleProduct.sku}}" stepKey="fillProductSku"/> + + <!--Trigger SEO drop down--> + <conditionalClick selector="{{AdminProductFormBundleSection.seoDropdown}}" dependentSelector="{{AdminProductFormBundleSection.seoDependent}}" visible="false" stepKey="OpenDropDownIfClosed"/> + <waitForPageLoad stepKey="WaitForDropDownSEO"/> + + <!--Fill URL input--> + <fillField userInput="{{BundleProduct.urlKey}}" selector="{{AdminProductFormBundleSection.urlKey}}" stepKey="FillsinSEOlinkExtension"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/EnableDisableProductActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/EnableDisableProductActionGroup.xml new file mode 100644 index 0000000000000..cdd13185cd0e3 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/ActionGroup/EnableDisableProductActionGroup.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AncillaryPrepBundleProduct"> + <!--Prereq: go to bundle product creation page--> + <fillField selector="{{AdminProductFormBundleSection.productName}}" userInput="{{BundleProduct.name}}" stepKey="fillProductName"/> + <fillField selector="{{AdminProductFormBundleSection.productSku}}" userInput="{{BundleProduct.sku}}" stepKey="fillProductSku"/> + + <!--Trigger SEO drop down--> + <conditionalClick selector="{{AdminProductFormBundleSection.seoDropdown}}" dependentSelector="{{AdminProductFormBundleSection.seoDependent}}" visible="false" stepKey="OpenDropDownIfClosed"/> + <waitForPageLoad stepKey="WaitForDropDownSEO"/> + + <!--Fill URL input--> + <fillField userInput="{{BundleProduct.urlKey}}" selector="{{AdminProductFormBundleSection.urlKey}}" stepKey="FillsinSEOlinkExtension"/> + </actionGroup> + + <!--Edit existing product by searching in product catalog--> + <actionGroup name="FindProductToEdit"> + <amOnPage url="{{ProductCatalogPage.url}}" stepKey="GoToProductCatalog"/> + <waitForPageLoad stepKey="WaitForCatalogProductPageToLoad"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> + <fillField userInput="{{BundleProduct.name}}" selector="#fulltext" stepKey="EnterProductNameInSearch"/> + <click stepKey="ClickSearch" selector="{{AdminProductFormBundleSection.searchButton}}"/> + <click stepKey="ClickOnProduct" selector="{{AdminProductFormBundleSection.firstCatalogProduct}}"/> + <waitForPageLoad stepKey="WaitForProductEditPageToLoad"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/BundleLinkData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/BundleLinkData.xml new file mode 100644 index 0000000000000..65add76a12af3 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/BundleLinkData.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="ApiBundleLink" type="bundle_link"> + <var key="sku" entityKey="sku" entityType="product2"/> + <var key="option_id" entityKey="option_id" entityType="bundle_options"/> + <var key="sku" entityKey="sku" entityType="product"/> + <data key="qty">1</data> + <data key="is_default">1</data> + <data key="price">1.11</data> + <data key="price_type">1</data> + <data key="can_change_quantity">1</data> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/BundleOptionData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/BundleOptionData.xml new file mode 100644 index 0000000000000..02f70ec15cab8 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/BundleOptionData.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="DropdownBundleOption" type="bundle_option"> + <data key="title" unique="suffix">bundle-option-dropdown</data> + <data key="required">true</data> + <data key="type">dropdown</data> + <data key="position">1</data> + <var key="sku" entityKey="sku" entityType="product2"/> + </entity> + <entity name="AllBundleOptions" type="bundle_options"> + <var key="sku" entityKey="sku" entityType="product"/> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/CustomAttributeData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/CustomAttributeData.xml new file mode 100644 index 0000000000000..c7f150e7ad6fb --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/CustomAttributeData.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="CustomAttributeDynamicPrice" type="custom_attribute"> + <data key="attribute_code">price_type</data> + <data key="value">0</data> + </entity> + <entity name="CustomAttributeFixPrice" type="custom_attribute"> + <data key="attribute_code">price_type</data> + <data key="value">1</data> + </entity> + <entity name="CustomAttributePriceView" type="custom_attribute"> + <data key="attribute_code">price_view</data> + <data key="value">1</data> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/ProductData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/ProductData.xml index a8598ded6ec17..3683721909ab2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/ProductData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Data/ProductData.xml @@ -7,10 +7,13 @@ --> <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> <entity name="BundleProduct" type="product"> <data key="name" unique="suffix">BundleProduct</data> + <data key="name" unique="suffix">BundleProduct</data> + <data key="name2" unique="suffix">BundleProduct2</data> <data key="sku" unique="suffix">bundleproduct</data> + <data key="sku2" unique="suffix">bundleproduct2</data> <data key="type_id">bundle</data> <data key="attribute_set_id">4</data> <data key="optionTitle1">BundleOption</data> @@ -18,5 +21,27 @@ <data key="defaultQuantity">10</data> <data key="status">1</data> <data key="urlKey" unique="suffix">bundleproduct</data> + <data key="urlKey2" unique="suffix">bundleproduct2</data> + <data key="default_quantity1">10</data> + <data key="default_quantity2">20</data> + <data key="set">4</data> + <data key="type">bundle</data> + <data key="fixedPrice">10</data> + <data key="fixedPriceFormatted">$10.00</data> + <data key="defaultAttribute">Default</data> + </entity> + <entity name="ApiBundleProduct" type="product2"> + <data key="name" unique="suffix">Api Bundle Product</data> + <data key="sku" unique="suffix">api-bundle-product</data> + <data key="type_id">bundle</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="status">1</data> + <data key="urlKey" unique="suffix">api-bundle-product</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute">ApiProductShortDescription</requiredEntity> + <requiredEntity type="custom_attribute">CustomAttributeDynamicPrice</requiredEntity> + <requiredEntity type="custom_attribute">CustomAttributePriceView</requiredEntity> </entity> </entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Metadata/bundle_link-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Metadata/bundle_link-meta.xml new file mode 100644 index 0000000000000..be881a7e98d65 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Metadata/bundle_link-meta.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="CreateBundleLink" dataType="bundle_link" type="create" auth="adminOauth" url="/V1/bundle-products/{sku}/links/{option_id}" method="POST"> + <contentType>application/json</contentType> + <object dataType="bundle_link" key="linkedProduct"> + <field key="sku">string</field> + <field key="option_id">integer</field> + <field key="qty">integer</field> + <field key="position">integer</field> + <field key="is_default">boolean</field> + <field key="price">number</field> + <field key="price_type">integer</field> + <field key="can_change_quantity">integer</field> + </object> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Metadata/bundle_option-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Metadata/bundle_option-meta.xml new file mode 100644 index 0000000000000..991c01ec4c6f0 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Metadata/bundle_option-meta.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="CreateBundleOption" dataType="bundle_option" type="create" auth="adminOauth" url="/V1/bundle-products/options/add" method="POST"> + <contentType>application/json</contentType> + <object dataType="bundle_option" key="option"> + <field key="title">string</field> + <field key="required">boolean</field> + <field key="type">string</field> + <field key="position">integer</field> + <field key="sku">string</field> + </object> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Metadata/bundle_options-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Metadata/bundle_options-meta.xml new file mode 100644 index 0000000000000..a81d5dda6a40b --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Metadata/bundle_options-meta.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="GetAllBundleOptions" dataType="bundle_options" type="get" auth="adminOauth" url="/V1/bundle-products/{sku}/options/all" method="GET"> + <contentType>application/json</contentType> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Page/AdminCatalogProductPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Page/AdminCatalogProductPage.xml new file mode 100644 index 0000000000000..f3e9366bb2bf6 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Page/AdminCatalogProductPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="AdminCatalogProductPage" url="catalog/product/" area="admin" module="Magento_Bundle"> + <section name="AdminCatalogProductSection"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Page/AdminProductCreatePage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Page/AdminProductCreatePage.xml index 95b68cb6e4367..5a17304ab28b8 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Page/AdminProductCreatePage.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Page/AdminProductCreatePage.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + --> <pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> <page name="AdminProductCreatePage" url="catalog/product/new/set/{{set}}/type/{{type}}/" area="admin" module="Magento_Catalog" parameterized="true"> <section name="AdminProductFormBundleSection"/> </page> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Section/AdminProductFormBundleSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Section/AdminProductFormBundleSection.xml index 551d0e44b58ae..6bc65d2d18491 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Section/AdminProductFormBundleSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Section/AdminProductFormBundleSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="AdminProductFormBundleSection"> <element name="bundleItemsToggle" type="button" selector="//span[text()='Bundle Items']"/> <element name="shipmentType" type="select" selector=".admin__control-select[name='product[shipment_type]']"/> @@ -21,5 +21,44 @@ <element name="bundleOptionXRequired" type="checkbox" selector="[name='bundle_options[bundle_options][{{x}}][required]']" parameterized="true"/> <element name="bundleOptionXProductYQuantity" type="input" selector="[name='bundle_options[bundle_options][{{x}}][bundle_selections][{{y}}][selection_qty]']" parameterized="true"/> <element name="addProductsToOption" type="button" selector="[data-index='modal_set']" timeout="30"/> + <!--Select"url Key"InputForm--> + <element name="urlKey" type="input" selector="//input[@name='product[url_key]']" timeout="30"/> + <!--AddSelectedProducts--> + <element name="addSelectedProducts" type="button" selector="//span[contains(text(),'Add Selected Products')]/ancestor::button" timeout="30"/> + <!--DefaultQuantities--> + <element name="defaultQuantity1" type="input" selector="//input[@name='bundle_options[bundle_options][0][bundle_selections][0][selection_qty]']" timeout="30"/> + <element name="defaultQuantity2" type="input" selector="//input[@name='bundle_options[bundle_options][0][bundle_selections][1][selection_qty]']" timeout="30"/> + <element name="productName" type="input" selector="//*[@name='product[name]']"/> + <element name="productSku" type="input" selector="//*[@name='product[sku]']"/> + <!--TestingForLocationOfOptions--> + <element name="bundleOptionSelector" type="button" selector="//*[@id='bundle-slide']/span"/> + <element name="bundleOptionSelection" type="button" selector="//div[@class='nested options-list']/div[2]/label[@class='label']"/> + <!--SelectorsForDescriptionCreationOnBundleProduct--> + <element name="contentDropDown" type="button" selector="div[data-index='content']" timeout="30"/> + <element name="contentDropDownIfNotShowing" type="button" selector="//div[@data-index='content']//div[contains(@class, '_hide')]"/> + <element name="longDescription" type="input" selector="#product_form_description"/> + <element name="shortDescription" type="input" selector="#product_form_short_description"/> + <!--BundleOptinsDropDown--> + <element name="bundleOptionsDropDown" type="button" selector="div[data-index='bundle-items']" timeout="30"/> + <!--AddingAnOption--> + <element name="addOptions" type="button" selector="//tr[@data-repeat-index='0']//td[4]" timeout="30"/> + <!--SEODropdownTab--> + <element name="seoDropdown" type="button" selector="//div[@data-index='search-engine-optimization']"/> + <element name="seoDependent" type="button" selector="//div[@data-index='search-engine-optimization']//div[contains(@class, '_show')]"/> + <!--NameOfProductOnProductPage--> + <element name="bundleProductName" type="text" selector="//*[@id='maincontent']//span[@itemprop='name']"/> + <!--EnableDisableToggle--> + <element name="enableDisableToggle" type="button" selector="//*[@id='container']//input[@name='product[status]']/.." timeout="30"/> + <!--SearchButton--> + <element name="searchButton" type="button" selector="//div[@class='data-grid-search-control-wrap']//*[@type='button']" timeout="30"/> + <!--ClickOnFirstProductInCatalog--> + <element name="firstCatalogProduct" type="button" selector="//table[@class='data-grid data-grid-draggable']/tbody/tr[@class='data-row']/td[4]"/> + <element name="bundledItems" type="block" selector="[data-index=bundle-items]"/> + <element name="dynamicPrice" type="button" selector="//div[@data-index='price_type']//div[@data-role='switcher']" timeout="30"/> + <element name="priceField" type="input" selector="//div[@data-index='price']//input"/> + <element name="listedBundleItem" type="text" selector="//tr[@data-repeat-index='0']//div"/> + <element name="listedBundleItem2" type="text" selector="//tr[@data-repeat-index='2']//div"/> + <!--FirstProductOption--> + <element name="firstProductOption" type="checkbox" selector="//div[@class='admin__data-grid-outer-wrap']//tr[@data-repeat-index='0']//input[@type='checkbox']"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Section/BundleStorefrontSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Section/BundleStorefrontSection.xml new file mode 100644 index 0000000000000..b7ca65b28c9bb --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Section/BundleStorefrontSection.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="BundleStorefrontSection"> + <!--TestingForLocationOfOptions--> + <element name="bundleOptionSelector" type="button" selector="//*[@id='bundle-slide']/span"/> + <element name="bundleOptionSelection" type="button" selector="//div[@class='nested options-list']/div[2]/label[@class='label']"/> + <!--Description--> + <!--CE exclusively--> + <element name="longDescriptionText" type="text" selector="//*[@id='description']/div/div" timeout="30"/> + <element name="shortDescriptionText" type="text" selector="//div[@class='product attribute overview']" timeout="30"/> + <!--NameOfProductOnProductPage--> + <element name="bundleProductName" type="text" selector="//*[@id='maincontent']//span[@itemprop='name']"/> + <!--PageNotFoundErrorMessage--> + <element name="pageNotFound" type="text" selector="//h1[@class='page-title']//span[contains(., 'Whoops, our bad...')]"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Section/StorefrontBundledSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Section/StorefrontBundledSection.xml new file mode 100644 index 0000000000000..2b9a1ca624f79 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Section/StorefrontBundledSection.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="StorefrontBundledSection"> + <element name="nthBundledOption" type="input" selector=".option:nth-of-type({{numOption}}) .choice:nth-of-type({{numOptionSelect}}) input" parameterized="true"/> + <element name="addToCart" type="button" selector="#bundle-slide" timeout="30"/> + <element name="addToCartConfigured" type="button" selector="#product-addtocart-button" timeout="30"/> + <element name="updateCart" type="button" selector="#product-updatecart-button" timeout="30"/> + <element name="configuredPrice" type="block" selector=".price-configured_price .price"/> + <element name="fixedPricing" type="text" selector="//div[@class='price-box price-final_price']//span[@id]//..//span[contains(text(),'{{var1}}')]" parameterized="true"/> + <element name="customizeProduct" type="button" selector="//*[@id='bundle-slide']"/> + <element name="customizableBundleItemOption" type="text" selector="//div[@class='field choice'][1]//input[@type='checkbox']"/> + <element name="customizableBundleItemOption2" type="text" selector="//div[@class='field choice'][2]//input[@type='checkbox']"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminAddBundleItemsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminAddBundleItemsTest.xml new file mode 100644 index 0000000000000..c46f052db59ac --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminAddBundleItemsTest.xml @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminAddBundleItemsTest"> + <annotations> + <features value="Bundle"/> + <stories value="Create/Edit bundle product in Admin"/> + <title value="Admin should be able to add/edit bundle items when creating/editing a bundle product"/> + <description value="Admin should be able to add/edit bundle items when creating/editing a bundle product"/> + <severity value="MAJOR"/> + <testCaseId value="MC-223"/> + <group value="Bundle"/> + </annotations> + <before> + <!--Creating data--> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct0"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct3"/> + <!--Admin login--> + <actionGroup stepKey="loginToAdminPanel" ref="LoginAsAdmin"/> + </before> + <after> + <!--Deleting data--> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="simpleProduct0" stepKey="deleteSimpleProduct0"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + <deleteData createDataKey="simpleProduct3" stepKey="deleteSimpleProduct3"/> + <!--Logging out--> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Go to bundle product creation page--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage"/> + <waitForPageLoad stepKey="waitForBundleProductCreatePageToLoad"/> + + <!-- Add two bundle items --> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions"> + <argument name="product" value="$$simpleProduct0$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions2"> + <argument name="product" value="$$simpleProduct1$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow2"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty1"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty2"/> + + <!--Fill out ancillary data on bundle product--> + <actionGroup ref="AncillaryPrepBundleProduct" stepKey="createBundledProductForTwoSimpleProducts"> + <argument name="bundleProduct" value="BundleProduct"/> + </actionGroup> + + <!--Save the product--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton"/> + <see userInput="You saved the product." stepKey="messageYouSavedTheProductIsShown"/> + + <!--Checking on admin side--> + <scrollToTopOfPage stepKey="scroll"/> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems2"/> + <seeElement stepKey="LookingForBundleItemPresence" selector="{{AdminProductFormBundleSection.listedBundleItem}}"/> + + <!--Checking on customer side--> + <amOnPage url="{{BundleProduct.urlKey}}.html" stepKey="GoToProductPage"/> + <waitForPageLoad stepKey="waitForBundleProductPageToLoad"/> + <seeElement selector="{{StorefrontBundledSection.customizeProduct}}" stepKey="LookingForAbilityToAddOptions"/> + <click selector="{{StorefrontBundledSection.customizeProduct}}" stepKey="clickButtonToCustomize"/> + <waitForPageLoad stepKey="waitCustomizationDropDown"/> + <seeElement selector="{{StorefrontBundledSection.customizableBundleItemOption}}" stepKey="seeBundleItem"/> + + <!--Add another bundle option with 2 items--> + <!--Go to bundle product creation page--> + <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage"/> + <waitForPageLoad stepKey="WaitForPageToLoad"/> + <conditionalClick selector="{{AdminProductFiltersSection.filtersClear}}" dependentSelector="{{AdminProductFiltersSection.filtersClear}}" visible="true" stepKey="ClickOnButtonToRemoveFiltersIfPresent"/> + <waitForPageLoad stepKey="WaitForClear"/> + <actionGroup ref="filterProductGridByName" stepKey="filterBundleProductOptionsDownToName"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + <click selector="{{AdminProductFormBundleSection.addOptions}}" stepKey="clickOnBundleProductToEdit"/> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItemsToEdit"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('1')}}" stepKey="waitForBundleOptionsToAppear"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('1')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillNewestOptionTitle"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('1')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectNewInputType"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToNewBundle"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToNewOption"/> + <waitForPageLoad stepKey="waitForPageLoadAfterNewBundleProducts"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterNewBundleProductOptions"> + <argument name="product" value="$$simpleProduct2$$"/> + </actionGroup> + <checkOption selector="//div[@class='admin__data-grid-outer-wrap']//tr[@data-repeat-index='0']//input[@type='checkbox']" stepKey="selectNewFirstGridRow"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterNewBundleProductOptions2"> + <argument name="product" value="$$simpleProduct3$$"/> + </actionGroup> + <checkOption selector="{{AdminProductFormBundleSection.firstProductOption}}" stepKey="selectNewFirstGridRow2"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddNewSelectedBundleProducts"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '2')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillNewProductDefaultQty1"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '3')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillNewProductDefaultQty2"/> + + <!--Save the product--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButtonAgain"/> + <see userInput="You saved the product." stepKey="messageYouSavedTheProductIsShownAgain"/> + + <!--Checking on admin side--> + <scrollToTopOfPage stepKey="scrollAgain"/> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenNewSectionBundleItems2"/> + <seeElement selector="{{AdminProductFormBundleSection.listedBundleItem2}}" stepKey="LookingForNewBundleItemPresence"/> + + <!--Checking on customer side--> + <amOnPage url="{{BundleProduct.urlKey}}.html" stepKey="GoToProductPageAgain"/> + <waitForPageLoad stepKey="waitForBundleProductPageToLoadAgain"/> + <seeElement selector="{{StorefrontBundledSection.customizeProduct}}" stepKey="LookingForAbilityToAddBothOptions"/> + <click selector="{{StorefrontBundledSection.customizeProduct}}" stepKey="clickButtonAgainToCustomize"/> + <waitForPageLoad stepKey="waitForBothCustomizationDropDown"/> + <seeElement selector="{{StorefrontBundledSection.customizableBundleItemOption2}}" stepKey="seeBundleItems"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminAddDefaultImageBundleProductTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminAddDefaultImageBundleProductTest.xml index 064c57958f37b..6a145b98a1816 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminAddDefaultImageBundleProductTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminAddDefaultImageBundleProductTest.xml @@ -42,6 +42,8 @@ <!-- Add two bundle items --> <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <!-- scrollTo before click to fix flaky failure --> + <scrollTo selector="{{AdminProductFormBundleSection.addOption}}" stepKey="scrollToAddOption"/> <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminAttributeSetSelectionTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminAttributeSetSelectionTest.xml new file mode 100644 index 0000000000000..abf8ed3a8bc87 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminAttributeSetSelectionTest.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminAttributeSetSelectionTest"> + <annotations> + <features value="Bundle"/> + <stories value="Create/Edit bundle product in Admin"/> + <title value="Admin should be able to select/edit the “Attributes Set” when creating/editing a bundle product"/> + <description value="Admin should be able to select/edit the “Attributes Set” when creating/editing a bundle product"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-221"/> + <group value="Bundle"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + </after> + <!-- Create a new attribute set --> + <amOnPage url="{{AdminProductAttributeSetGridPage.url}}" stepKey="goToAttributeSets"/> + <waitForPageLoad stepKey="wait1"/> + <click selector="{{AdminProductAttributeSetGridSection.addAttributeSetBtn}}" stepKey="clickAddAttributeSet"/> + <fillField selector="{{AdminProductAttributeSetSection.name}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="fillName"/> + <selectOption selector="{{AdminProductAttributeSetSection.basedOn}}" userInput="Default" stepKey="selectDefaultSet"/> + <click selector="{{AdminProductAttributeSetSection.saveBtn}}" stepKey="clickSave1"/> + <dragAndDrop selector1="{{AdminProductAttributeSetSection.attribute('meta_keyword')}}" selector2="{{AdminProductAttributeSetSection.attribute('manufacturer')}}" stepKey="unassign1"/> + <click selector="{{AdminProductAttributeSetSection.addNewGroupBtn}}" stepKey="clickAddNewGroup"/> + <fillField selector="{{AdminProductAttributeSetSection.newGroupName}}" userInput="TestGroupName" stepKey="fillNewGroupName"/> + <click selector="{{AdminProductAttributeSetSection.modalOk}}" stepKey="clickOkInModal"/> + <dragAndDrop selector1="{{AdminProductAttributeSetSection.attribute('manufacturer')}}" selector2="{{AdminProductAttributeSetSection.attribute('TestGroupName')}}" stepKey="assignManufacturer"/> + <click selector="{{AdminProductAttributeSetSection.saveBtn}}" stepKey="clickSave2"/> + + <!-- Go to new product page and see a default attribute --> + <!-- Switch from default attribute set to new attribute set --> + <amOnPage url="{{AdminProductCreatePage.url('4', 'bundle')}}" stepKey="goToNewProductPage"/> + <waitForPageLoad stepKey="wait2"/> + <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> + <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="searchForAttrSet"/> + <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + <fillField selector="{{AdminProductFormBundleSection.productName}}" userInput="{{BundleProduct.name}}" stepKey="fillProductName"/> + <fillField selector="{{AdminProductFormBundleSection.productSku}}" userInput="{{BundleProduct.sku}}" stepKey="fillProductSku"/> + + <!--save the product/published by default--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="messageYouSavedTheProductIsShown"/> + + <!--Testing that price appears correctly in admin catalog--> + <!--Set filter to product name--> + <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage"/> + <waitForPageLoad stepKey="WaitForPageToLoad"/> + <actionGroup ref="filterProductGridByName" stepKey="filterBundleProductOptionsDownToName"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + <seeElement selector="{{AdminProductFiltersSection.attributeSetOfFirstRow(ProductAttributeFrontendLabel.label)}}" stepKey="seeAttributeSet"/> + + <!--Editing Attribute set--> + <click selector="{{AdminProductFiltersSection.attributeSetOfFirstRow(ProductAttributeFrontendLabel.label)}}" stepKey="clickAttributeSet2"/> + <waitForPageLoad stepKey="waitForPageLoad2"/> + + <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet2"/> + <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{BundleProduct.defaultAttribute}}" stepKey="searchForAttrSet2"/> + <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet2"/> + + <!--save the product/published by default--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton2"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="messageYouSavedTheProductIsShown2"/> + + <!--Testing that price appears correctly in admin catalog--> + <!--Set filter to product name--> + <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage2"/> + <waitForPageLoad stepKey="WaitForPageToLoad2"/> + <actionGroup ref="filterProductGridByName" stepKey="filterBundleProductOptionsDownToName2"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + <seeElement selector="{{AdminProductFiltersSection.attributeSetOfFirstRow(BundleProduct.defaultAttribute)}}" stepKey="seeAttributeSet2"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminDeleteABundleProduct.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminDeleteABundleProduct.xml new file mode 100644 index 0000000000000..5c2244e85a061 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminDeleteABundleProduct.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminDeleteABundleProduct"> + <annotations> + <features value="Bundle"/> + <stories value="Admin list bundle products"/> + <title value="Admin should be able to delete a bundle product"/> + <description value="Admin should be able to delete a bundle product"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-216"/> + <group value="Bundle"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + </before> + <after> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + </after> + + <!--Create bundle product--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage"/> + <waitForPageLoad stepKey="waitForBundleProductCreationPage"/> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions"> + <argument name="product" value="$$simpleProduct1$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions2"> + <argument name="product" value="$$simpleProduct2$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow2"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty1"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty2"/> + + <!--Fill out ancillary data on bundle product--> + <actionGroup ref="AncillaryPrepBundleProduct" stepKey="createBundledProductForTwoSimpleProducts"/> + + <!--Save the product--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="messageYouSavedTheProductIsShown"/> + + <!--Go to catalog deletion page--> + <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="goToCatalogPage"/> + <waitForPageLoad stepKey="Loading"/> + + <!--Apply Name Filter--> + <actionGroup ref="filterProductGridByName" stepKey="filterBundleProductOptionsDownToName"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + <click selector="{{AdminProductFiltersSection.allCheckbox}}" stepKey="SelectAllOnly1"/> + <waitForPageLoad stepKey="loading2"/> + + <!--Delete--> + <click selector="{{AdminProductFiltersSection.actions}}" stepKey="ClickOnActionsChangingView"/> + <click selector="{{AdminProductFiltersSection.delete}}" stepKey="ClickDelete"/> + <click selector="//button[@class='action-primary action-accept']" stepKey="ConfirmDelete"/> + <waitForPageLoad stepKey="loading3"/> + + <!--Locating delete message--> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="deleteMessage"/> + + <!--Testing deletion of product--> + <amOnPage url="{{BundleProduct.urlKey}}.html" stepKey="GoToProductPageAgain"/> + <waitForPageLoad stepKey="WaitForProductPageToLoadToShowElement"/> + <dontSeeElement selector="{{BundleStorefrontSection.bundleProductName}}" stepKey="LookingForNameOfProductTwo"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminFilterProductListByBundleProduct.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminFilterProductListByBundleProduct.xml new file mode 100644 index 0000000000000..ad4e90a050a40 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminFilterProductListByBundleProduct.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminFilterProductListByBundleProduct"> + <annotations> + <features value="Bundle"/> + <stories value="Admin list bundle products"/> + <title value="Admin should be able to filter product list by type = Bundle Product"/> + <description value="Admin should be able to filter product list by type = Bundle Product"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-214"/> + <group value="Bundle"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + </before> + <after> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + </after> + + <!--Create bundle product--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage"/> + <waitForPageLoad stepKey="waitForBundleProductCreationPage"/> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions"> + <argument name="product" value="$$simpleProduct1$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions2"> + <argument name="product" value="$$simpleProduct2$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow2"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty1"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty2"/> + + <!--Fill out ancillary data on bundle product--> + <actionGroup ref="AncillaryPrepBundleProduct" stepKey="createBundledProductForTwoSimpleProducts"/> + + <!--Save the product--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="messageYouSavedTheProductIsShown"/> + + <!--Apply Bundle Product Filter--> + <!--Clear Filters--> + <actionGroup ref="AdminClearFiltersActionGroup" stepKey="ClearFilters"/> + + <!--Setting filter--> + <actionGroup ref="BundleProductFilter" stepKey="FilterForOnlyBundleProducts"/> + + <!--Testing application of filter--> + <see selector="{{AdminProductFiltersSection.productType('0')}}" userInput="Bundle Product" stepKey="correcType0"/> + <dontSeeElement selector="{{AdminProductFiltersSection.AllProductsNotOfBundleType}}" stepKey="checkingRowsForIncorrectType"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminMassDeleteBundleProducts.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminMassDeleteBundleProducts.xml new file mode 100644 index 0000000000000..ca692e5d9374d --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminMassDeleteBundleProducts.xml @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminMassDeleteBundleProductsTest"> + <annotations> + <features value="Bundle"/> + <stories value="Admin list bundle products"/> + <title value="Admin should be able to mass delete bundle products"/> + <description value="Admin should be able to mass delete bundle products"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-218"/> + <group value="Bundle"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct3"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct4"/> + </before> + <after> + <!--Clear Filters--> + <actionGroup ref="AdminClearFiltersActionGroup" stepKey="ClearFiltersAfter"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + <deleteData createDataKey="simpleProduct3" stepKey="deleteSimpleProduct3"/> + <deleteData createDataKey="simpleProduct4" stepKey="deleteSimpleProduct4"/> + </after> + + <!--Go to bundle product creation page--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage" /> + <waitForPageLoad stepKey="waitForBundleProductCreatePageToLoad"/> + + <!--Create bundle product--> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions"> + <argument name="product" value="$$simpleProduct1$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions2"> + <argument name="product" value="$$simpleProduct2$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow2"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty1"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty2"/> + + <!--Fill out ancillary data on bundle product--> + <actionGroup ref="AncillaryPrepBundleProduct" stepKey="createBundledProductForTwoSimpleProducts"> + <argument name="bundleProduct" value="BundleProduct"/> + </actionGroup> + + <!--Save the product--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="messageYouSavedTheProductIsShown"/> + + <!--Creating Second bundle product--> + <!--Go to bundle product creation page--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage2" /> + <waitForPageLoad stepKey="waitForBundleProductCreatePageToLoad2"/> + + <!--Create bundle product 2--> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems2"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption32"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions2"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle2"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType2"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle2"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption2"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts2"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptionsx2"> + <argument name="product" value="$$simpleProduct3$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRowx2"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions22"> + <argument name="product" value="$$simpleProduct4$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow22"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts2"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty12"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty22"/> + + <fillField selector="{{AdminProductFormBundleSection.productName}}" userInput="{{BundleProduct.name2}}" stepKey="fillProductName2"/> + <fillField selector="{{AdminProductFormBundleSection.productSku}}" userInput="{{BundleProduct.sku2}}" stepKey="fillProductSku2"/> + + <!--Trigger SEO drop down--> + <conditionalClick selector="{{AdminProductFormBundleSection.seoDropdown}}" dependentSelector="{{AdminProductFormBundleSection.seoDependent}}" visible="false" stepKey="OpenDropDownIfClosed2"/> + <waitForPageLoad stepKey="WaitForDropDownSEO"/> + + <!--Fill URL input--> + <fillField userInput="{{BundleProduct.urlKey2}}" selector="{{AdminProductFormBundleSection.urlKey}}" stepKey="FillsinSEOlinkExtension2"/> + + <!--Save the product--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton2"/> + <see userInput="You saved the product." stepKey="messageYouSavedTheProductIsShown2"/> + + <!--Mass delete bundle products--> + <!--Clear Filters--> + <actionGroup ref="AdminClearFiltersActionGroup" stepKey="ClearFilters"/> + + <!--Setting filter--> + <actionGroup ref="BundleProductFilter" stepKey="FilterForOnlyBundleProducts"/> + + <!--Delete--> + <click selector="{{AdminProductFiltersSection.allCheckbox}}" stepKey="SelectAllOnly1"/> + <waitForPageLoad stepKey="loading"/> + <click selector="{{AdminProductFiltersSection.actions}}" stepKey="ClickOnActionsChangingView"/> + <click selector="{{AdminProductFiltersSection.delete}}" stepKey="ClickDelete"/> + <click selector="//button[@class='action-primary action-accept']" stepKey="ConfirmDelete"/> + <waitForPageLoad stepKey="loading3"/> + + <!--Locating delete message--> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="deleteMessage"/> + + <!--Clear Cache - resets products according to enabled/disabled view--> + <actionGroup ref="ClearPageCacheActionGroup" stepKey="ClearPageCaches"/> + + <!--Testing deletion of products--> + <amOnPage url="{{BundleProduct.urlKey}}.html" stepKey="GoToProductPageAgain"/> + <waitForPageLoad stepKey="WaitForProductPageToLoadToShowElement"/> + <dontSeeElement stepKey="LookingForNameOfProduct" selector="{{BundleStorefrontSection.bundleProductName}}"/> + <seeElement stepKey="LookingForPageNotFoundMessage" selector="{{BundleStorefrontSection.pageNotFound}}"/> + <amOnPage url="{{BundleProduct.urlKey2}}.html" stepKey="GoToProductPageAgain2"/> + <waitForPageLoad stepKey="WaitForProductPageToLoadToShowElement2"/> + <dontSeeElement stepKey="LookingForNameOfProduct2" selector="{{BundleStorefrontSection.bundleProductName}}"/> + <seeElement stepKey="LookingForPageNotFoundMessage2" selector="{{BundleStorefrontSection.pageNotFound}}"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminProductBundleCreationTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminProductBundleCreationTest.xml new file mode 100644 index 0000000000000..2641919e204fa --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminProductBundleCreationTest.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminProductBundleCreationTest"> + <annotations> + <features value="Bundle"/> + <stories value="Create/Edit bundle product in Admin"/> + <title value="Admin should be able to save and publish a bundle product"/> + <description value="Admin should be able to save and publish a bundle product"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-225"/> + <group value="Bundle"/> + </annotations> + <before> + <!--Creating Data--> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + + <!-- Admin Login--> + <actionGroup stepKey="loginToAdminPanel" ref="LoginAsAdmin"/> + </before> + <after> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!-- go to bundle product creation page--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage" /> + <waitForPageLoad stepKey="waitForBundleProductCreatePageToLoad"/> + + <!-- Add two bundle items --> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions"> + <argument name="product" value="$$simpleProduct1$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions2"> + <argument name="product" value="$$simpleProduct2$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow2"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty1"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty2"/> + + <!--Create a bundle product with ancillary data--> + <actionGroup ref="CreateBasicBundleProduct" stepKey="createBundledProduct"> + <argument name="bundleProduct" value="BundleProduct"/> + </actionGroup> + + <!--save the product/published by default--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="messageYouSavedTheProductIsShown"/> + + <!-- go to page--> + <amOnPage url="{{BundleProduct.urlKey}}.html" stepKey="GoToProductPage"/> + + <!--Test Assertion - on correct page/page has been published--> + <waitForPageLoad stepKey="waitForBundleProductPageToLoad"/> + <seeElement stepKey="LookingForNameOfProduct" selector="{{BundleStorefrontSection.bundleProductName}}"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminRemoveDefaultImageBundleProductTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminRemoveDefaultImageBundleProductTest.xml index 3dec79cf1b054..6c3be47a1cb7a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminRemoveDefaultImageBundleProductTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/AdminRemoveDefaultImageBundleProductTest.xml @@ -42,6 +42,8 @@ <!-- Add two bundle items --> <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <!-- scrollTo before click to fix flaky failure --> + <scrollTo selector="{{AdminProductFormBundleSection.addOption}}" stepKey="scrollToAddOption"/> <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/BundleProductFixedPricingTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/BundleProductFixedPricingTest.xml new file mode 100644 index 0000000000000..0df2619ab6db2 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/BundleProductFixedPricingTest.xml @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="BundleProductFixedPricingTest"> + <annotations> + <features value="Bundle"/> + <stories value="Bundle Product Pricing"/> + <title value="Admin should be able to apply fixed pricing for Bundled Product"/> + <description value="Admin should be able to apply fixed pricing for Bundled Product"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-186"/> + <group value="Bundle"/> + </annotations> + <before> + <!--Creating data--> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + + <!--Admin login--> + <actionGroup stepKey="loginToAdminPanel" ref="LoginAsAdmin"/> + </before> + <after> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Go to bundle product creation page--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage" /> + <waitForPageLoad stepKey="waitForBundleProductCreatePageToLoad"/> + + <!-- Add two bundle items --> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions"> + <argument name="product" value="$$simpleProduct1$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions2"> + <argument name="product" value="$$simpleProduct2$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow2"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty1"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty2"/> + + <!--Fill out ancillary data on bundle product--> + <actionGroup ref="AncillaryPrepBundleProduct" stepKey="createBundledProductForTwoSimpleProducts"> + <argument name="bundleProduct" value="BundleProduct"/> + </actionGroup> + + <!--Disable dynamic pricing and enter fixed price of product--> + <scrollToTopOfPage stepKey="scrollToTopOfPage"/> + <click selector="{{AdminProductFormBundleSection.dynamicPrice}}" stepKey="clickDynamicPriceSwitcher"/> + <fillField userInput="{{BundleProduct.fixedPrice}}" selector="{{AdminProductFormBundleSection.priceField}}" stepKey="fillPrice"/> + + <!--Save the product--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="messageYouSavedTheProductIsShown"/> + + <!--Testing that price appears correctly in admin catalog--> + <!--Set filter to product name--> + <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage"/> + <waitForPageLoad stepKey="WaitForPageToLoad"/> + <conditionalClick selector="{{AdminProductFiltersSection.filtersClear}}" dependentSelector="{{AdminProductFiltersSection.filtersClear}}" visible="true" stepKey="ClickOnButtonToRemoveFiltersIfPresent"/> + <waitForPageLoad stepKey="WaitForClear"/> + <actionGroup ref="filterProductGridByName" stepKey="filterBundleProductOptionsDownToName"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + <seeElement selector="{{AdminProductFiltersSection.priceOfFirstRow(BundleProduct.fixedPrice)}}" stepKey="seePrice"/> + <!--Storefront--> + <amOnPage url="{{BundleProduct.urlKey}}.html" stepKey="GoToProductPage"/> + <waitForPageLoad stepKey="waitForProductPageToLoad"/> + <seeElement selector="{{StorefrontBundledSection.fixedPricing(BundleProduct.fixedPrice)}}" stepKey="checkingForFixedPrice"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/EnableDisableBundleProductStatusTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/EnableDisableBundleProductStatusTest.xml new file mode 100644 index 0000000000000..5588d30619c48 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/EnableDisableBundleProductStatusTest.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="EnableDisableBundleProductStatusTest"> + <annotations> + <features value="Bundle"/> + <stories value="Admin list bundle products"/> + <title value="Admin should be able to change a bundle product status to Enabled/Disabled"/> + <description value="Admin should be able to change a bundle product status to Enabled/Disabled"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-215"/> + <group value="Bundle"/> + </annotations> + <before> + <!--Creating data--> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + + <!--Admin login--> + <actionGroup stepKey="loginToAdminPanel" ref="LoginAsAdmin"/> + </before> + <after> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Go to bundle product creation page--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage" /> + <waitForPageLoad stepKey="waitForBundleProductCreatePageToLoad"/> + + <!-- Add two bundle items --> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions"> + <argument name="product" value="$$simpleProduct1$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions2"> + <argument name="product" value="$$simpleProduct2$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow2"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty1"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty2"/> + + <!--Fill out ancillary data on bundle product--> + <actionGroup ref="AncillaryPrepBundleProduct" stepKey="createBundledProductForTwoSimpleProducts"> + <argument name="bundleProduct" value="BundleProduct"/> + </actionGroup> + + <!--Save the product--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="messageYouSavedTheProductIsShown"/> + + <!--Testing enabled view--> + <!--Product enabled by default--> + <!--Go to page--> + <amOnPage url="{{BundleProduct.urlKey}}.html" stepKey="GoToProductPage"/> + <waitForPageLoad stepKey="waitForBundleProductPageToLoad"/> + <seeElement stepKey="LookingForNameOfProduct" selector="{{BundleStorefrontSection.bundleProductName}}"/> + + <!--Testing disabled view--> + <actionGroup ref="FindProductToEdit" stepKey="FindProductEditPage"/> + <click stepKey="ClickOnEnableDisableToggle" selector="{{AdminProductFormBundleSection.enableDisableToggle}}"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButtonAgain"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="messageYouSavedTheProductIsShown2"/> + <waitForPageLoad stepKey="PauseForSave"/> + <amOnPage url="{{BundleProduct.urlKey}}.html" stepKey="GoToProductPageAgain"/> + <waitForPageLoad stepKey="WaitForProductPageToLoadToShowElement"/> + <dontSeeElement stepKey="LookingForNameOfProductTwo" selector="{{BundleStorefrontSection.bundleProductName}}"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/MassEnableDisableBundleProductsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/MassEnableDisableBundleProductsTest.xml new file mode 100644 index 0000000000000..2754cbcccab7c --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/MassEnableDisableBundleProductsTest.xml @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="MassEnableDisableBundleProductsTest"> + <annotations> + <features value="Bundle"/> + <stories value="Admin list bundle products"/> + <title value="Admin should be able to mass change bundle products status to Enabled/Disabled"/> + <description value="Admin should be able to mass change bundle products status to Enabled/Disabled"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-217"/> + <group value="Bundle"/> + <!--Skipped due to MAGETWO-92898--> + <group value="skip"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct3"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct4"/> + </before> + <after> + <!--Clear Filters--> + <actionGroup ref="AdminClearFiltersActionGroup" stepKey="ClearFiltersAfter"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + <deleteData createDataKey="simpleProduct3" stepKey="deleteSimpleProduct3"/> + <deleteData createDataKey="simpleProduct4" stepKey="deleteSimpleProduct4"/> + </after> + + <!--Go to bundle product creation page--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage" /> + <waitForPageLoad stepKey="waitForBundleProductCreatePageToLoad"/> + + <!--Create bundle product--> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions"> + <argument name="product" value="$$simpleProduct1$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions2"> + <argument name="product" value="$$simpleProduct2$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow2"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty1"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty2"/> + + <fillField selector="{{AdminProductFormBundleSection.productName}}" userInput="{{BundleProduct.name}}" stepKey="fillProductName"/> + <fillField selector="{{AdminProductFormBundleSection.productSku}}" userInput="{{BundleProduct.sku}}" stepKey="fillProductSku"/> + + <!--Trigger SEO drop down--> + <conditionalClick selector="{{AdminProductFormBundleSection.seoDropdown}}" dependentSelector="{{AdminProductFormBundleSection.seoDependent}}" visible="false" stepKey="OpenDropDownIfClosed"/> + <waitForPageLoad stepKey="WaitForDropDownSEO"/> + + <!--Fill URL input--> + <fillField userInput="{{BundleProduct.urlKey}}" selector="{{AdminProductFormBundleSection.urlKey}}" stepKey="FillsinSEOlinkExtension"/> + + <!--Save the product--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="messageYouSavedTheProductIsShown"/> + + <!--Creating Second bundle product--> + <!--Go to bundle product creation page--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage2" /> + <waitForPageLoad stepKey="waitForBundleProductCreatePageToLoad2"/> + + <!--Create bundle product 2--> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems2"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption32"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions2"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle2"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType2"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle2"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption2"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts2"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptionsx2"> + <argument name="product" value="$$simpleProduct3$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRowx2"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions22"> + <argument name="product" value="$$simpleProduct4$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow22"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts2"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty12"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty22"/> + + <fillField selector="{{AdminProductFormBundleSection.productName}}" userInput="{{BundleProduct.name2}}" stepKey="fillProductName2"/> + <fillField selector="{{AdminProductFormBundleSection.productSku}}" userInput="{{BundleProduct.sku2}}" stepKey="fillProductSku2"/> + + <!--Trigger SEO drop down--> + <conditionalClick selector="{{AdminProductFormBundleSection.seoDropdown}}" dependentSelector="{{AdminProductFormBundleSection.seoDependent}}" visible="false" stepKey="OpenDropDownIfClosed2"/> + <waitForPageLoad stepKey="WaitForDropDownSEO2"/> + + <!--Fill URL input--> + <fillField userInput="{{BundleProduct.urlKey2}}" selector="{{AdminProductFormBundleSection.urlKey}}" stepKey="FillsinSEOlinkExtension2"/> + + <!--Save the product--> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton2"/> + <see userInput="You saved the product." stepKey="messageYouSavedTheProductIsShown2"/> + + <!--Clear Filters--> + <actionGroup ref="AdminClearFiltersActionGroup" stepKey="ClearFilters"/> + + <!--Setting filter--> + <actionGroup ref="BundleProductFilter" stepKey="FilterForOnlyBundleProducts"/> + + <!--Disabling bundle products--> + <click selector="{{AdminProductFiltersSection.allCheckbox}}" stepKey="ClickOnSelectAllCheckBox"/> + <click selector="{{AdminProductFiltersSection.actions}}" stepKey="ClickOnActions"/> + <click selector="{{AdminProductFiltersSection.changeStatus}}" stepKey="ClickOnChangeStatus"/> + <click selector="{{AdminProductFiltersSection.disable}}" stepKey="ClickOnDisable"/> + <waitForPageLoad stepKey="waitForPageloadToExecute"/> + + <!--Clear Cache - reindex - resets products according to enabled/disabled view--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + <actionGroup ref="ClearPageCacheActionGroup" stepKey="clearing"/> + + <!--Confirm bundle products have been disabled--> + <amOnPage url="{{BundleProduct.urlKey2}}.html" stepKey="GoToProductPage"/> + <waitForPageLoad stepKey="WaitForProductPageToLoadToShowElement"/> + <dontSeeElement stepKey="LookingForNameOfProductDisabled" selector="{{BundleStorefrontSection.bundleProductName}}"/> + + <!--Enabling bundle products--> + <amOnPage url="{{ProductCatalogPage.url}}" stepKey="GoToCatalogPageChangingView"/> + <waitForPageLoad stepKey="WaitForPageToLoadFullyChangingView"/> + <click selector="{{AdminProductFiltersSection.allCheckbox}}" stepKey="ClickOnSelectAllCheckBoxChangingView"/> + <click selector="{{AdminProductFiltersSection.actions}}" stepKey="ClickOnActionsChangingView"/> + <click selector="{{AdminProductFiltersSection.changeStatus}}" stepKey="ClickOnChangeStatusChangingView"/> + <click selector="{{AdminProductFiltersSection.enable}}" stepKey="ClickOnEnable"/> + + <!--Clear Cache - reindex - resets products according to enabled/disabled view--> + <magentoCLI command="indexer:reindex" stepKey="reindex2"/> + <magentoCLI command="cache:flush" stepKey="flushCache2"/> + + <!--Confirm bundle products have been enabled--> + <amOnPage url="{{BundleProduct.urlKey2}}.html" stepKey="GoToProductPageEnabled"/> + <waitForPageLoad stepKey="waitForBundleProductPageToLoad"/> + <seeElement stepKey="LookingForNameOfProduct" selector="{{BundleStorefrontSection.bundleProductName}}"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/NewBundleProductSelectionTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/NewBundleProductSelectionTest.xml new file mode 100644 index 0000000000000..cb19b9f996d56 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/NewBundleProductSelectionTest.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="NewBundleProductSelectionTest"> + <annotations> + <features value="Bundle"/> + <stories value="Create/Edit bundle product in Admin"/> + <title value="Admin should be able to select a “Bundle Product” product type when adding a new product"/> + <description value="Admin should be able to select a “Bundle Product” product type when adding a new product"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-220"/> + <group value="Bundle"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + </after> + <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage"/> + <waitForPageLoad stepKey="WaitForPageToLoad"/> + <!--Selecting new bundle product--> + <actionGroup ref="goToCreateProductPage" stepKey="goToCreateBundleProduct"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + <!--Testing if on the bundle product creation page--> + <seeElement selector="{{AdminProductFormBundleSection.bundleOptionsDropDown}}" stepKey="CheckForPresenceOfBundleProductFeatures"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/StorefrontAdminEditDataTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/StorefrontAdminEditDataTest.xml new file mode 100644 index 0000000000000..2bdb2c3e5ab17 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/StorefrontAdminEditDataTest.xml @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontAdminEditDataTest"> + <annotations> + <features value="Bundle"/> + <stories value="Bundle products list on Storefront"/> + <title value="Customer should be able to see chosen options for Bundle Product in Shopping Cart when Option Title is edited in Admin"/> + <description value="Customer should be able to see chosen options for Bundle Product in Shopping Cart when Option Title is edited in Admin"/> + <severity value="MAJOR"/> + <testCaseId value="MC-291"/> + <group value="Bundle"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + </before> + <after> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + </after> + + <!-- Create a bundle product --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPageBundle"/> + <waitForPageLoad stepKey="waitForProductPageLoadBundle"/> + <actionGroup ref="goToCreateProductPage" stepKey="goToCreateBundleProduct"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + + <actionGroup ref="fillProductNameAndSkuInProductForm" stepKey="fillBundleProductNameAndSku"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + + <!-- Add two bundle items --> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <scrollTo stepKey="scrollToBundleItems" selector="{{AdminProductFormBundleSection.bundledItems}}"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions"> + <argument name="product" value="$$simpleProduct1$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions2"> + <argument name="product" value="$$simpleProduct2$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow2"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty1"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty2"/> + + <click stepKey="saveProductBundle" selector="{{AdminProductFormActionSection.saveButton}}"/> + <see stepKey="assertSuccess" selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product."/> + + <!-- Go to the storefront bundled product page --> + <amOnPage url="/{{BundleProduct.urlKey}}.html" stepKey="visitStoreFrontBundle"/> + <waitForPageLoad stepKey="waitForStorefront"/> + <click stepKey="customizeAndAddToCart" selector="{{StorefrontBundledSection.addToCart}}"/> + <waitForPageLoad stepKey="waitCustomizableOptionsPopUp"/> + + <!-- add one product to the shopping cart --> + <click stepKey="selectFirstBundleOption" selector="{{StorefrontBundledSection.nthBundledOption('1','1')}}"/> + <waitForPageLoad stepKey="waitForPriceUpdate"/> + <see stepKey="seeSinglePrice" selector="{{StorefrontBundledSection.configuredPrice}}" userInput="1,230.00"/> + <click stepKey="addFirstItemToCart" selector="{{StorefrontBundledSection.addToCartConfigured}}"/> + <waitForPageLoad stepKey="waitForElementAdded"/> + + <!-- Go to the shopping cart page and grab the value of the option title --> + <amOnPage url="/checkout/cart/" stepKey="onPageShoppingCart"/> + <waitForPageLoad stepKey="waitForCartPageLoad"/> + <grabTextFrom selector="{{CheckoutCartProductSection.nthBundleOptionName('1')}}" stepKey="grabTotalBefore"/> + + <!-- Find the product that we just created using the product grid --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage"/> + <waitForPageLoad stepKey="waitForAdminProductPageLoad"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> + <actionGroup ref="filterProductGridBySku" stepKey="findCreatedProduct"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + <waitForPageLoad stepKey="waitForProductFilterLoad"/> + <click selector="{{AdminProductGridSection.firstRow}}" stepKey="clickOnProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + + <!-- Change the product option title --> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="BundleOption2" stepKey="fillOptionTitle2"/> + <click stepKey="saveProductAttribute2" selector="{{AdminProductFormActionSection.saveButton}}"/> + <see stepKey="assertSuccess2" selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product."/> + + <!-- Go to the shopping cart page and make sure the title has changed --> + <amOnPage url="/checkout/cart/" stepKey="onPageShoppingCart1"/> + <waitForPageLoad stepKey="waitForCartPageLoad1"/> + <grabTextFrom selector="{{CheckoutCartProductSection.nthBundleOptionName('1')}}" stepKey="grabTotalAfter"/> + <assertNotEquals expected="{$grabTotalBefore}" expectedType="string" actual="{$grabTotalAfter}" actualType="string" stepKey="assertNotEquals"/> + + <!-- Delete the bundled product --> + <actionGroup stepKey="deleteBundle" ref="deleteProductUsingProductGrid"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/StorefrontEditBundleProductTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/StorefrontEditBundleProductTest.xml new file mode 100644 index 0000000000000..1944f82cf3181 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Bundle/Test/StorefrontEditBundleProductTest.xml @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontEditBundleProductTest"> + <annotations> + <features value="Bundle"/> + <stories value="Bundle products list on Storefront"/> + <title value="Customer should be able to change chosen options for Bundle Product when clicking Edit button in Shopping Cart page"/> + <description value="Customer should be able to change chosen options for Bundle Product when clicking Edit button in Shopping Cart page"/> + <severity value="MAJOR"/> + <testCaseId value="MC-290"/> + <group value="Bundle"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + </before> + <after> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + </after> + + <!-- Create a bundle product --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPageBundle"/> + <waitForPageLoad stepKey="waitForProductPageLoadBundle"/> + <actionGroup ref="goToCreateProductPage" stepKey="goToCreateBundleProduct"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + + <actionGroup ref="fillProductNameAndSkuInProductForm" stepKey="fillBundleProductNameAndSku"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + + <!-- Add two bundle items --> + <conditionalClick selector="{{AdminProductFormBundleSection.bundleItemsToggle}}" dependentSelector="{{AdminProductFormBundleSection.bundleItemsToggle}}" visible="false" stepKey="conditionallyOpenSectionBundleItems"/> + <scrollTo stepKey="scrollToBundleItems" selector="{{AdminProductFormBundleSection.bundledItems}}"/> + <click selector="{{AdminProductFormBundleSection.addOption}}" stepKey="clickAddOption3"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" stepKey="waitForBundleOptions"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXTitle('0')}}" userInput="{{BundleProduct.optionTitle1}}" stepKey="fillOptionTitle"/> + <selectOption selector="{{AdminProductFormBundleSection.bundleOptionXInputType('0')}}" userInput="{{BundleProduct.optionInputType1}}" stepKey="selectInputType"/> + <waitForElementVisible selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="waitForAddProductsToBundle"/> + <click selector="{{AdminProductFormBundleSection.addProductsToOption}}" stepKey="clickAddProductsToOption"/> + <waitForPageLoad stepKey="waitForPageLoadAfterBundleProducts"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions"> + <argument name="product" value="$$simpleProduct1$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterBundleProductOptions2"> + <argument name="product" value="$$simpleProduct2$$"/> + </actionGroup> + <checkOption selector="{{AdminAddProductsToOptionPanel.firstCheckbox}}" stepKey="selectFirstGridRow2"/> + <click selector="{{AdminAddProductsToOptionPanel.addSelectedProducts}}" stepKey="clickAddSelectedBundleProducts"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '0')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty1"/> + <fillField selector="{{AdminProductFormBundleSection.bundleOptionXProductYQuantity('0', '1')}}" userInput="{{BundleProduct.defaultQuantity}}" stepKey="fillProductDefaultQty2"/> + + <click stepKey="saveProductBundle" selector="{{AdminProductFormActionSection.saveButton}}"/> + <see stepKey="assertSuccess" selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product."/> + + <!-- Go to the storefront bundled product page --> + <amOnPage url="/{{BundleProduct.urlKey}}.html" stepKey="visitStoreFrontBundle"/> + <waitForPageLoad stepKey="waitForStorefront"/> + <click stepKey="customizeAndAddToCart" selector="{{StorefrontBundledSection.addToCart}}"/> + <waitForPageLoad stepKey="waitCustomizableOptionsPopUp"/> + + <!-- add two products to the shopping cart, each with one different option --> + <click stepKey="selectFirstBundleOption" selector="{{StorefrontBundledSection.nthBundledOption('1','1')}}"/> + <waitForPageLoad stepKey="waitForPriceUpdate"/> + <see stepKey="seeSinglePrice" selector="{{StorefrontBundledSection.configuredPrice}}" userInput="1,230.00"/> + <click stepKey="addFirstItemToCart" selector="{{StorefrontBundledSection.addToCartConfigured}}"/> + <waitForPageLoad stepKey="waitForElementAdded"/> + + <click stepKey="unselectFirstBundleOption" selector="{{StorefrontBundledSection.nthBundledOption('1','1')}}"/> + <click stepKey="selectSecondBundleOption" selector="{{StorefrontBundledSection.nthBundledOption('1','2')}}"/> + <waitForPageLoad stepKey="waitForPriceUpdate2"/> + <see stepKey="seeSinglePrice2" selector="{{StorefrontBundledSection.configuredPrice}}" userInput="1,230.00"/> + <click stepKey="addSecondItemToCart" selector="{{StorefrontBundledSection.addToCartConfigured}}"/> + <waitForPageLoad stepKey="waitForElementAdded2"/> + + <!-- Go to the shopping cart page and edit the first product --> + <amOnPage url="/checkout/cart/" stepKey="onPageShoppingCart"/> + <waitForPageLoad stepKey="waitForCartPageLoad"/> + <waitForElementVisible stepKey="waitForInfoDropdown" selector="{{CheckoutCartSummarySection.total}}"/> + <waitForPageLoad stepKey="waitForCartPageLoad3"/> + <grabTextFrom selector="{{CheckoutCartSummarySection.total}}" stepKey="grabTotalBefore"/> + <click stepKey="clickEdit" selector="{{CheckoutCartProductSection.nthEditButton('1')}}"/> + <waitForPageLoad stepKey="waitForStorefront2"/> + + <!-- Choose both of the options on the storefront --> + <click stepKey="selectFirstBundleOption2" selector="{{StorefrontBundledSection.nthBundledOption('1','1')}}"/> + <click stepKey="selectSecondBundleOption2" selector="{{StorefrontBundledSection.nthBundledOption('1','2')}}"/> + + <waitForPageLoad stepKey="waitForPriceUpdate3"/> + <see stepKey="seeDoublePrice" selector="{{StorefrontBundledSection.configuredPrice}}" userInput="2,460.00"/> + + <click stepKey="addFirstItemToCart2" selector="{{StorefrontBundledSection.updateCart}}"/> + <waitForPageLoad stepKey="waitForElementAdded3"/> + + <!-- Go to the shopping cart page --> + <amOnPage url="/checkout/cart/" stepKey="onPageShoppingCart2"/> + <waitForPageLoad stepKey="waitForCartPageLoad2"/> + + <!-- Assert that the options are both there and the proce no longer matches --> + <see stepKey="assertBothOptions" selector="{{CheckoutCartProductSection.nthItemOption('2')}}" userInput="$$simpleProduct1.sku$$"/> + <see stepKey="assertBothOptions2" selector="{{CheckoutCartProductSection.nthItemOption('2')}}" userInput="$$simpleProduct2.sku$$"/> + <waitForElementVisible stepKey="waitForInfoDropdown2" selector="{{CheckoutCartSummarySection.total}}"/> + <waitForPageLoad stepKey="waitForCartPageLoad4"/> + <grabTextFrom selector="{{CheckoutCartSummarySection.total}}" stepKey="grabTotalAfter"/> + <assertNotEquals expected="{$grabTotalBefore}" expectedType="string" actual="{$grabTotalAfter}" actualType="string" stepKey="assertNotEquals"/> + + <!-- Delete the bundled product --> + <actionGroup stepKey="deleteBundle" ref="deleteProductUsingProductGrid"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AddProductToCartActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AddProductToCartActionGroup.xml index 6caa4fef770b1..9380c3052a5f5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AddProductToCartActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AddProductToCartActionGroup.xml @@ -14,5 +14,6 @@ <amOnPage url="/{{product.name}}.html" stepKey="navigateProductPage"/> <click selector="{{StorefrontProductPageSection.addToCartBtn}}" stepKey="addToCart"/> <waitForElementVisible selector="{{StorefrontProductPageSection.successMsg}}" time="30" stepKey="waitForProductAdded"/> + <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added {{product.name}} to your shopping cart." stepKey="seeAddedToCartMessage"/> </actionGroup> </actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminCategoryActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminCategoryActionGroup.xml index 96e40e348a6f2..1125a776bbdbd 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminCategoryActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminCategoryActionGroup.xml @@ -37,6 +37,16 @@ <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Category" stepKey="seeCategoryPageTitle"/> </actionGroup> + <!-- Go to admin category page by id --> + <actionGroup name="goToAdminCategoryPageById"> + <arguments> + <argument name="id" type="string"/> + </arguments> + <amOnPage url="{{AdminCategoryEditPage.url(id)}}" stepKey="amOnAdminCategoryPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="{{id}}" stepKey="seeCategoryPageTitle"/> + </actionGroup> + <!-- Fill category fields --> <actionGroup name="fillCategoryForm"> <arguments> @@ -57,7 +67,7 @@ <!--Upload image for category --> <actionGroup name="addCategoryImage"> <arguments> - <argument name="image" defaultValue="ImageUpload"/> + <argument name="image" defaultValue="ProductImage"/> </arguments> <conditionalClick selector="{{AdminCategoryContentSection.sectionHeader}}" dependentSelector="{{AdminCategoryContentSection.uploadButton}}" visible="false" stepKey="openContentSection"/> <waitForPageLoad time="30" stepKey="waitForPageLoad"/> @@ -81,7 +91,7 @@ <actionGroup name="checkCategoryImageInAdmin"> <arguments> - <argument name="image" defaultValue="ImageUpload"/> + <argument name="image" defaultValue="ProductImage"/> </arguments> <conditionalClick selector="{{AdminCategoryContentSection.sectionHeader}}" dependentSelector="{{AdminCategoryContentSection.uploadButton}}" visible="false" stepKey="openContentSection"/> <waitForPageLoad stepKey="waitForPageLoad"/> @@ -89,6 +99,18 @@ <see selector="{{AdminCategoryContentSection.imageFileName}}" userInput="{{image.file}}" stepKey="seeImage"/> </actionGroup> + <!-- Action to navigate to Media Gallery. Used in tests to cleanup uploaded images --> + <actionGroup name="navigateToMediaGallery"> + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="amOnAdminCategoryPage"/> + <waitForElementVisible selector="{{AdminCategoryContentSection.sectionHeader}}" stepKey="waitForContentSection"/> + <conditionalClick selector="{{AdminCategoryContentSection.sectionHeader}}" dependentSelector="{{AdminCategoryContentSection.uploadButton}}" visible="false" stepKey="openContentSection"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <waitForElementVisible selector="{{AdminCategoryContentSection.selectFromGalleryButton}}" stepKey="waitForSelectFromGalleryButton"/> + <click selector="{{AdminCategoryContentSection.selectFromGalleryButton}}" stepKey="clickSelectFromGalleryButton"/> + <waitForPageLoad stepKey="waitForPageLoad2"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear"/> + </actionGroup> + <!--Actions to check if a category exists on StoreFront--> <actionGroup name="CheckCategoryOnStorefront"> <arguments> @@ -118,6 +140,68 @@ <dontSee selector="{{AdminCategorySidebarTreeSection.categoryInTree(categoryEntity.name)}}" stepKey="dontSeeCategoryInTree"/> </actionGroup> + <!-- Actions to fill out a new category from the product page--> + <!-- The action assumes that you are already on an admin product configuration page --> + <actionGroup name="FillNewProductCategory" > + <arguments> + <argument name="categoryName" defaultValue="Test Category" type="string"/> + <argument name="parentCategoryName" defaultValue="default" type="string"/> + </arguments> + + <!-- Click on new Category --> + <click stepKey="clickNewCategory" selector="{{AdminProductCategoryCreationSection.newCategory}}"/> + <waitForPageLoad stepKey="waitForFieldSet"/> + + <fillField stepKey="fillCategoryName" selector="{{AdminProductCategoryCreationSection.nameInput}}" userInput="{{categoryName}}"/> + + <!-- Search and select a parent catagory for the product --> + <click stepKey="clickParentCategory" selector="{{AdminProductCategoryCreationSection.parentCategory}}"/> + <waitForPageLoad stepKey="waitForDropDownVisible"/> + <fillField stepKey="searchForParent" userInput="{{parentCategoryName}}" selector="{{AdminProductCategoryCreationSection.parentSearch}}"/> + <waitForPageLoad stepKey="waitForFieldResults"/> + <click stepKey="clickParent" selector="{{AdminProductCategoryCreationSection.parentSearchResult}}"/> + + <click stepKey="createCategory" selector="{{AdminProductCategoryCreationSection.createCategory}}"/> + <waitForPageLoad stepKey="waitForCategoryCreated"/> + </actionGroup> + + <!-- Actions to delete the category last made --> + <actionGroup name="DeleteMostRecentCategory"> + + <amOnPage url="/{{AdminCategoryPage.url}}" stepKey="goToCategoryFrontPage"/> + + <waitForPageLoad stepKey="waitForCategoryPageLoad"/> + + <click stepKey="goToCreateCategory" selector="{{AdminCategorySidebarTreeSection.lastCreatedCategory}}" /> + <waitForPageLoad stepKey="waitForCreatedCategoryPageLoad"/> + + <click stepKey="clickDeleteCategory" selector="{{AdminCategoryMainActionsSection.DeleteButton}}" /> + <waitForPageLoad stepKey="waitForModalVisible"/> + + <click stepKey="clickOkToDelete" selector="{{AdminCategoryModalSection.ok}}" /> + + <waitForPageLoad stepKey="waitForModalNotVisible"/> + + </actionGroup> + + <!-- Actions to check if a certain category is present on the page --> + <actionGroup name="CategoryPresent" > + <arguments> + <argument name="categoryName" defaultValue="Test Category" type="string"/> + </arguments> + + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="goToCategoryAdminPage"/> + <waitForPageLoad stepKey="waitForCategoryAdminPageLoad"/> + + <see userInput="{{categoryName}}" stepKey="assertCategoryOnAdminPage" selector="{{AdminCategorySidebarTreeSection.treeContainer}}"/> + + <amOnPage url="/{{categoryName}}.html" stepKey="goToCustomerFrontPage"/> + + <see userInput="{{categoryName}}" stepKey="assertCategoryNameOnStorefront" selector="{{StorefrontCategoryMainSection.CategoryTitle}}"/> + + <waitForPageLoad stepKey="waitForCustomerCategoryPageLoad"/> + </actionGroup> + <!--Check that name field is required--> <actionGroup name="CheckCategoryNameIsRequiredField"> <seeInCurrentUrl url="{{AdminCategoryPage.url}}" stepKey="seeOnCategoryPage"/> @@ -128,6 +212,25 @@ <see selector="{{AdminCategoryBasicFieldSection.FieldError('uid')}}" userInput="This is a required field." stepKey="seeErrorMessage"/> </actionGroup> + <actionGroup name="switchCategoryStoreView"> + <arguments> + <argument name="Store"/> + <argument name="CatName"/> + </arguments> + <amOnPage url="{{AdminCategoryPage.page}}" stepKey="amOnCategoryPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(CatName)}}" stepKey="navigateToCreatedCategory" /> + <waitForPageLoad stepKey="waitForPageLoad2"/> + <waitForLoadingMaskToDisappear stepKey="waitForSpinner"/> + <scrollToTopOfPage stepKey="scrollToToggle"/> + <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewDropdownToggle}}" stepKey="openStoreViewDropDown"/> + <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewOption(Store)}}" stepKey="selectStoreView"/> + <waitForPageLoad stepKey="waitForPageLoad3"/> + <waitForLoadingMaskToDisappear stepKey="waitForSpinner2"/> + <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" stepKey="selectStoreViewAccept"/> + <waitForPageLoad stepKey="waitForStoreViewChangeLoad"/> + </actionGroup> + <actionGroup name="navigateToCreatedCategory"> <arguments> <argument name="Category"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductActionGroup.xml index 22835c7fa2e54..3ef8b961a81af 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductActionGroup.xml @@ -77,14 +77,14 @@ <!--Upload image for product--> <actionGroup name="addProductImage"> <arguments> - <argument name="image" defaultValue="ImageUpload"/> + <argument name="image" defaultValue="ProductImage"/> </arguments> <conditionalClick selector="{{AdminProductImagesSection.productImagesToggle}}" dependentSelector="{{AdminProductImagesSection.imageUploadButton}}" visible="false" stepKey="openProductImagesSection"/> <waitForPageLoad time="30" stepKey="waitForPageRefresh"/> <waitForElementVisible selector="{{AdminProductImagesSection.imageUploadButton}}" stepKey="seeImageSectionIsReady"/> <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="{{image.file}}" stepKey="uploadFile"/> - <waitForAjaxLoad time="30" stepKey="waitForAjaxUpload"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoading"/> + <waitForElementNotVisible selector="{{AdminProductImagesSection.uploadProgressBar}}" stepKey="waitForUpload"/> + <waitForElementVisible selector="{{AdminProductImagesSection.imageFile(image.fileName)}}" stepKey="waitForThumbnail"/> </actionGroup> <!--Remove image for product--> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductAttributeSetActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductAttributeSetActionGroup.xml new file mode 100644 index 0000000000000..19e5bed0913a3 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductAttributeSetActionGroup.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AssignAttributeToGroup"> + <arguments> + <argument name="group" type="string"/> + <argument name="attribute" type="string"/> + </arguments> + <conditionalClick selector="{{AdminProductAttributeSetEditSection.attributeGroupExtender(group)}}" dependentSelector="{{AdminProductAttributeSetEditSection.attributeGroupCollapsed(group)}}" visible="true" stepKey="extendGroup"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <dragAndDrop selector1="{{AdminProductAttributeSetEditSection.unassignedAttribute(attribute)}}" selector2="{{AdminProductAttributeSetEditSection.xThLineItemAttributeGroup(group, '1')}}" stepKey="dragAndDropToGroupProductDetails"/> + <waitForPageLoad stepKey="waitForPageLoad2"/> + <see userInput="{{attribute}}" selector="{{AdminProductAttributeSetEditSection.groupTree}}" stepKey="seeAttributeInGroup"/> + </actionGroup> + <actionGroup name="UnassignAttributeFromGroup"> + <arguments> + <argument name="group" type="string"/> + <argument name="attribute" type="string"/> + </arguments> + <conditionalClick selector="{{AdminProductAttributeSetEditSection.attributeGroupExtender(group)}}" dependentSelector="{{AdminProductAttributeSetEditSection.attributeGroupCollapsed(group)}}" visible="true" stepKey="extendGroup"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <dragAndDrop selector1="{{AdminProductAttributeSetEditSection.assignedAttribute(attribute)}}" selector2="{{AdminProductAttributeSetEditSection.xThLineItemUnassignedAttribute('1')}}" stepKey="dragAndDropToUnassigned"/> + <waitForPageLoad stepKey="waitForPageLoad2"/> + <see userInput="{{attribute}}" selector="{{AdminProductAttributeSetEditSection.unassignedAttributesTree}}" stepKey="seeAttributeInUnassigned"/> + </actionGroup> + <actionGroup name="SaveAttributeSet"> + <click selector="{{AdminProductAttributeSetActionSection.save}}" stepKey="clickSave"/> + <see userInput="You saved the attribute set" selector="{{AdminMessagesSection.success}}" stepKey="successMessage"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductGridActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductGridActionGroup.xml index 6398010f06687..5f2c45b829780 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductGridActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductGridActionGroup.xml @@ -153,6 +153,27 @@ <click selector="{{AdminProductGridConfirmActionSection.ok}}" stepKey="confirmProductDelete"/> </actionGroup> + <!--Delete a product by filtering grid and using delete action--> + <actionGroup name="deleteProductBySku"> + <arguments> + <argument name="sku" type="string"/> + </arguments> + <!--TODO use other action group for filtering grid when MQE-539 is implemented --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage"/> + <waitForPageLoad time="60" stepKey="waitForPageLoadInitial"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> + <click selector="{{AdminProductGridFilterSection.filters}}" stepKey="openProductFilters"/> + <fillField selector="{{AdminProductGridFilterSection.skuFilter}}" userInput="{{sku}}" stepKey="fillProductSkuFilter"/> + <click selector="{{AdminProductGridFilterSection.applyFilters}}" stepKey="clickApplyFilters"/> + <see selector="{{AdminProductGridSection.productGridCell('1', 'SKU')}}" userInput="{{sku}}" stepKey="seeProductSkuInGrid"/> + <click selector="{{AdminProductGridSection.multicheckDropdown}}" stepKey="openMulticheckDropdown"/> + <click selector="{{AdminProductGridSection.multicheckOption('Select All')}}" stepKey="selectAllProductInFilteredGrid"/> + <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickActionDropdown"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Delete')}}" stepKey="clickDeleteAction"/> + <waitForElementVisible selector="{{AdminProductGridConfirmActionSection.title}}" stepKey="waitForConfirmModal"/> + <click selector="{{AdminProductGridConfirmActionSection.ok}}" stepKey="confirmProductDelete"/> + </actionGroup> + <!--Open product for edit by clicking row X and column Y in product grid--> <actionGroup name="openProducForEditByClickingRowXColumnYInProductGrid"> <arguments> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/CustomOptionsActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/CustomOptionsActionGroup.xml new file mode 100644 index 0000000000000..0409c3f195013 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/CustomOptionsActionGroup.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + + + <actionGroup name="CreateCustomRadioOptions"> + + <!-- ActionGroup will add a single custom option to a product --> + <!-- You must already be on the product creation page --> + <arguments> + <argument name="customOptionName"/> + <argument name="productOption"/> + <argument name="productOption2"/> + </arguments> + + <click stepKey="clickAddOptions" selector="{{AdminProductCustomizableOptionsSection.addOptionBtn}}"/> + <waitForPageLoad stepKey="waitForAddProductPageLoad"/> + + <!-- Fill in the option and select the type of radio (once) --> + <fillField stepKey="fillInOptionTitle" selector="{{AdminProductCustomizableOptionsSection.lastOptionTitle}}" userInput="{{customOptionName}}"/> + <click stepKey="clickOptionTypeParent" selector="{{AdminProductCustomizableOptionsSection.lastOptionTypeParent}}"/> + <waitForPageLoad stepKey="waitForDropdownOpen"/> + <click stepKey="clickOptionType" selector="{{AdminProductCustomizableOptionsSection.optionType('Radio Buttons')}}"/> + + <!-- Add three radio options based on the parameter --> + <click stepKey="clickAddValue" selector="{{AdminProductCustomizableOptionsSection.addValue}}"/> + + <fillField stepKey="fillInValueTitle" selector="{{AdminProductCustomizableOptionsSection.valueTitle}}" userInput="{{productOption.title}}"/> + <fillField stepKey="fillInValuePrice" selector="{{AdminProductCustomizableOptionsSection.valuePrice}}" userInput="{{productOption.price}}"/> + + <click stepKey="clickAddValue2" selector="{{AdminProductCustomizableOptionsSection.addValue}}"/> + + <fillField stepKey="fillInValueTitle2" selector="{{AdminProductCustomizableOptionsSection.valueTitle}}" userInput="{{productOption2.title}}"/> + <fillField stepKey="fillInValuePrice2" selector="{{AdminProductCustomizableOptionsSection.valuePrice}}" userInput="{{productOption2.price}}"/> + + + </actionGroup> + +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/SearchAndMultiselectActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/SearchAndMultiselectActionGroup.xml index a0546ec8bca0e..784c40808f63b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/SearchAndMultiselectActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/SearchAndMultiselectActionGroup.xml @@ -10,13 +10,13 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> <actionGroup name="searchAndMultiSelectActionGroup"> <arguments> - <argument name="dropDownSelector"/> - <argument name="options"/> + <argument name="dropDownSelector" /> + <argument name="options" type="string"/> </arguments> <waitForPageLoad stepKey="waitForPageLoad"/> <waitForElementVisible selector="{{dropDownSelector}} .action-select.admin__action-multiselect" stepKey="waitForDropdown"/> <click selector="{{dropDownSelector}} .action-select.admin__action-multiselect" stepKey="clickDropdown"/> - <selectMultipleOptions filterSelector="{{dropDownSelector}} .admin__action-multiselect-search-wrap>input[data-role='advanced-select-text']" optionSelector="{{dropDownSelector}} .admin__action-multiselect-label>span" stepKey="selectSpecifiedOptions"> + <selectMultipleOptions filterSelector="{{dropDownSelector}} .admin__action-multiselect-search-wrap>input" optionSelector="{{dropDownSelector}} .admin__action-multiselect-label>span" stepKey="selectSpecifiedOptions"> <array>[{{options}}]</array> </selectMultipleOptions> </actionGroup> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductPageActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductPageActionGroup.xml index 4923b1d969b3b..f763b0c3d2768 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductPageActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductPageActionGroup.xml @@ -38,4 +38,20 @@ <fillField userInput="abcdefghjklansdmnbvdsasdfghjmn" selector="{{StorefrontProductPageSection.customTextOptionInput}}" stepKey="textInput5"/> <see selector="{{StorefrontProductPageSection.charCounter}}" userInput="(10 too many)" stepKey="assertHint5"/> </actionGroup> + <actionGroup name="checkAttributeInMoreInformationTab"> + <arguments> + <argument name="attributeLabel" type="string"/> + <argument name="attributeValue" type="string"/> + </arguments> + <click selector="{{StorefrontProductMoreInformationSection.moreInformation}}" stepKey="clickTab"/> + <see userInput="{{attributeLabel}}" selector="{{StorefrontProductMoreInformationSection.moreInformationTextArea}}" stepKey="seeAttributeLabel"/> + <see userInput="{{attributeValue}}" selector="{{StorefrontProductMoreInformationSection.moreInformationTextArea}}" stepKey="seeAttributeValue"/> + </actionGroup> + <actionGroup name="checkAttributeNotInMoreInformationTab"> + <arguments> + <argument name="attributeLabel" type="string"/> + </arguments> + <click selector="{{StorefrontProductMoreInformationSection.moreInformation}}" stepKey="clickTab"/> + <dontSee userInput="{{attributeLabel}}" selector="{{StorefrontProductMoreInformationSection.moreInformationTextArea}}" stepKey="seeAttributeLabel"/> + </actionGroup> </actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductAttributeOptionData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductAttributeOptionData.xml index b197fba1d281b..22d0e83d7b338 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductAttributeOptionData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductAttributeOptionData.xml @@ -27,4 +27,10 @@ <entity name="ProductAttributeOptionGetter" type="ProductAttributeOption"> <var key="attribute_code" entityKey="attribute_code" entityType="ProductAttribute"/> </entity> + <entity name="productAttributeOption" type="ProductAttributeOption"> + <var key="attribute_code" entityKey="attribute_code" entityType="ProductAttribute"/> + <data key="label" unique="suffix">customOption</data> + <data key="is_default">false</data> + <data key="sort_order">0</data> + </entity> </entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductData.xml index 34110d0417661..3c6e7d3ddc319 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductData.xml @@ -154,12 +154,13 @@ <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> <requiredEntity type="custom_attribute">CustomAttributeProductUrlKey</requiredEntity> </entity> - <entity name="ImageUpload" type="uploadImage"> + <entity name="ProductImage" type="uploadImage"> <data key="title" unique="suffix">Image1</data> <data key="price">1.00</data> <data key="file_type">Upload File</data> <data key="shareable">Yes</data> <data key="file">magento-logo.png</data> + <data key="fileName">magento-logo</data> </entity> <entity name="MagentoLogo" type="image"> <data key="title" unique="suffix">MagentoLogo</data> @@ -281,4 +282,41 @@ <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> <requiredEntity type="custom_attribute_array">ApiProductNewsFromDate</requiredEntity> </entity> + <entity name="SimpleProductNameWithDoubleQuote" type="product"> + <data key="name" unique="prefix">Double Quote"</data> + <data key="sku" unique="prefix">doubleQuote</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="price">10.00</data> + <data key="visibility">4</data> + <data key="status">1</data> + <data key="quantity">1000</data> + <data key="weight">1</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + </entity> + <entity name="GetProduct" type="product"> + <var key="sku" entityKey="sku" entityType="product"/> + </entity> + <entity name="GetProduct2" type="product2"> + <var key="sku" entityKey="sku" entityType="product2"/> + </entity> + <entity name="GetProduct3" type="product3"> + <var key="sku" entityKey="sku" entityType="product3"/> + </entity> + <entity name="ApiSimplePrice1" type="product"> + <data key="sku" unique="suffix">api-simple-product</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">Api Simple Product</data> + <data key="price">1.00</data> + </entity> + <entity name="ApiSimplePrice100" type="product"> + <data key="sku" unique="suffix">api-simple-product</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">Api Simple Product</data> + <data key="price">100.00</data> + </entity> </entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductOptionData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductOptionData.xml index f2f6e1a6f552f..2abc557d44d96 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductOptionData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Data/ProductOptionData.xml @@ -18,6 +18,16 @@ <data key="price_type">fixed</data> <data key="max_characters">0</data> </entity> + <entity name="ProductOptionField2" type="product_option"> + <var key="product_sku" entityType="product" entityKey="sku" /> + <data key="title">OptionField2</data> + <data key="type">field</data> + <data key="is_require">true</data> + <data key="sort_order">1</data> + <data key="price">20</data> + <data key="price_type">fixed</data> + <data key="max_characters">0</data> + </entity> <entity name="ProductOptionArea" type="product_option"> <var key="product_sku" entityType="product" entityKey="sku" /> <data key="title">OptionArea</data> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Metadata/product-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Metadata/product-meta.xml index edbf1133d4fae..b04b4bb98c854 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Metadata/product-meta.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Metadata/product-meta.xml @@ -60,7 +60,10 @@ </object> <field key="saveOptions">boolean</field> </operation> - <operation name="deleteProduct" dataType="product" type="delete" auth="adminOauth" url="/V1/products/{sku}" method="DELETE"> + <operation name="DeleteProduct" dataType="product" type="delete" auth="adminOauth" url="/V1/products/{sku}" method="DELETE"> + <contentType>application/json</contentType> + </operation> + <operation name="GetProduct" dataType="product" type="get" auth="adminOauth" url="/V1/products/{sku}" method="GET"> <contentType>application/json</contentType> </operation> <operation name="CreateProduct2" dataType="product2" type="create" auth="adminOauth" url="/V1/products" method="POST"> @@ -115,7 +118,43 @@ </object> <field key="saveOptions">boolean</field> </operation> - <operation name="deleteProduct2" dataType="product2" type="delete" auth="adminOauth" url="/V1/products/{sku}" method="DELETE"> + <operation name="DeleteProduct2" dataType="product2" type="delete" auth="adminOauth" url="/V1/products/{sku}" method="DELETE"> + <contentType>application/json</contentType> + </operation> + <operation name="GetProduct2" dataType="product2" type="get" auth="adminOauth" url="/V1/products/{sku}" method="GET"> + <contentType>application/json</contentType> + </operation> + <!-- Data type product3 is to work around MQE-1035 --> + <operation name="CreateProduct3" dataType="product3" type="create" auth="adminOauth" url="/V1/products" method="POST"> + <contentType>application/json</contentType> + <object dataType="product3" key="product"> + <field key="sku">string</field> + <field key="name">string</field> + <field key="attribute_set_id">integer</field> + <field key="price">number</field> + <field key="status">integer</field> + <field key="visibility">integer</field> + <field key="type_id">string</field> + <field key="created_at">string</field> + <field key="updated_at">string</field> + <field key="weight">integer</field> + <field key="extension_attributes">product_extension_attribute</field> + <array key="product_links"> + <value>product_link</value> + </array> + <array key="custom_attributes"> + <value>custom_attribute_array</value> + </array> + <array key="options"> + <value>product_option</value> + </array> + </object> + </operation> + <!-- Data type product3 is to work around MQE-1035 --> + <operation name="DeleteProduct3" dataType="product3" type="delete" auth="adminOauth" url="/V1/products/{sku}" method="DELETE"> + <contentType>application/json</contentType> + </operation> + <operation name="GetProduct3" dataType="product3" type="get" auth="adminOauth" url="/V1/products/{sku}" method="GET"> <contentType>application/json</contentType> </operation> </operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Metadata/product_link-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Metadata/product_link-meta.xml index a6d418dc675e7..899dc3a7f4a8c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Metadata/product_link-meta.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Metadata/product_link-meta.xml @@ -14,9 +14,9 @@ <field key="linked_product_sku">string</field> <field key="linked_product_type">string</field> <field key="position">integer</field> - <array key="extension_attributes"> - <value>product_link_extension_attribute</value> - </array> + <object key="extension_attributes" dataType="product_link_extension_attribute"> + <field key="qty">integer</field> + </object> </operation> <operation name="UpdateProductLink" dataType="product_link" type="update"> <field key="sku">string</field> @@ -24,8 +24,8 @@ <field key="linked_product_sku">string</field> <field key="linked_product_type">string</field> <field key="position">integer</field> - <array key="extension_attributes"> - <value>product_link_extension_attribute</value> - </array> + <object key="extension_attributes" dataType="product_link_extension_attribute"> + <field key="qty">integer</field> + </object> </operation> </operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Metadata/product_links-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Metadata/product_links-meta.xml new file mode 100644 index 0000000000000..34e8d0fca6833 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Metadata/product_links-meta.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="CreateProductLinks" dataType="product_links" type="create" auth="adminOauth" url="/V1/products/{sku}/links" method="POST"> + <contentType>application/json</contentType> + <array key="items"> + <value>product_link</value> + </array> + </operation> + <operation name="UpdateProductLinks" dataType="product_links" type="update" auth="adminOauth" url="/V1/products/{sku}/links" method="PUT"> + <contentType>application/json</contentType> + <field key="entity">product_link</field> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminCategoryEditPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminCategoryEditPage.xml new file mode 100644 index 0000000000000..95e80238d4af6 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminCategoryEditPage.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="AdminCategoryEditPage" url="catalog/category/edit/id/{{categoryId}}/" area="admin" module="Catalog" parameterized="true"> + <section name="AdminCategorySidebarActionSection"/> + <section name="AdminCategoryMainActionsSection"/> + <section name="AdminCategorySidebarTreeSection"/> + <section name="AdminCategoryBasicFieldSection"/> + <section name="AdminCategorySEOSection"/> + <section name="AdminCategoryProductsSection"/> + <section name="AdminCategoryProductsGridSection"/> + <section name="AdminCategoryModalSection"/> + <section name="AdminCategoryMessagesSection"/> + <section name="AdminCategoryContentSection"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminProductAttributeSetEditPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminProductAttributeSetEditPage.xml new file mode 100644 index 0000000000000..42a5be5e31334 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/AdminProductAttributeSetEditPage.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="AdminProductAttributeSetEditPage" url="catalog/product_set/edit/id" area="admin" module="Catalog"> + <section name="AdminProductAttributeSetEditSection"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/ProductCatalogPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/ProductCatalogPage.xml new file mode 100644 index 0000000000000..e56cc122c44cb --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Page/ProductCatalogPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + --> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="ProductCatalogPage" url="/catalog/product/" area="admin" module="Magento_Catalog"> + <section name="ProductCatalogPageSection"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryBasicFieldSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryBasicFieldSection.xml index 26f56f6176f98..7de2390e5348a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryBasicFieldSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryBasicFieldSection.xml @@ -11,9 +11,12 @@ <section name="AdminCategoryBasicFieldSection"> <element name="IncludeInMenu" type="checkbox" selector="input[name='include_in_menu']"/> <element name="includeInMenuLabel" type="text" selector="input[name='include_in_menu']+label"/> + <element name="includeInMenuUseDefault" type="checkbox" selector="input[name='use_default[include_in_menu]']"/> <element name="EnableCategory" type="checkbox" selector="input[name='is_active']"/> <element name="enableCategoryLabel" type="text" selector="input[name='is_active']+label"/> + <element name="enableUseDefault" type="checkbox" selector="input[name='use_default[is_active]']"/> <element name="CategoryNameInput" type="input" selector="input[name='name']"/> + <element name="categoryNameUseDefault" type="checkbox" selector="input[name='use_default[name]']"/> <element name="ContentTab" type="input" selector="input[name='name']"/> <element name="FieldError" type="text" selector=".admin__field-error[data-bind='attr: {for: {{field}}}, text: error']" parameterized="true"/> </section> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryMainActionsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryMainActionsSection.xml index 3c806fbbea63f..e726e5bfb7c63 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryMainActionsSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategoryMainActionsSection.xml @@ -11,5 +11,8 @@ <section name="AdminCategoryMainActionsSection"> <element name="SaveButton" type="button" selector=".page-actions-inner #save" timeout="30"/> <element name="DeleteButton" type="button" selector=".page-actions-inner #delete" timeout="30"/> + <element name="CategoryStoreViewDropdownToggle" type="button" selector="#store-change-button"/> + <element name="CategoryStoreViewOption" type="button" selector="//div[contains(@class, 'store-switcher')]//a[normalize-space()='{{store}}']" parameterized="true"/> + <element name="CategoryStoreViewModalAccept" type="button" selector=".modal-popup.confirm._show .action-accept"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySEOSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySEOSection.xml index 679cd2d7bee0d..0e01660d5fce9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySEOSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySEOSection.xml @@ -11,6 +11,8 @@ <section name="AdminCategorySEOSection"> <element name="SectionHeader" type="button" selector="div[data-index='search_engine_optimization']" timeout="30"/> <element name="UrlKeyInput" type="input" selector="input[name='url_key']"/> + <element name="UrlKeyDefaultValueCheckbox" type="button" selector="input[name='use_default[url_key]']"/> + <element name="UrlKeyRedirectCheckbox" type="button" selector="[data-index='url_key_create_redirect'] input[type='checkbox']"/> <element name="MetaTitleInput" type="input" selector="input[name='meta_title']"/> <element name="MetaKeywordsInput" type="textarea" selector="textarea[name='meta_keywords']"/> <element name="MetaDescriptionInput" type="textarea" selector="textarea[name='meta_description']"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml index e914c80c3e6ac..5e080bbb7fdba 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminCategorySidebarTreeSection.xml @@ -14,5 +14,7 @@ <element name="categoryTreeRoot" type="text" selector="div.x-tree-root-node>li.x-tree-node:first-of-type>div.x-tree-node-el:first-of-type" timeout="30"/> <element name="categoryInTree" type="text" selector="//a/span[contains(text(), '{{name}}')]" parameterized="true" timeout="30"/> <element name="categoryInTreeUnderRoot" type="text" selector="//div[@class='x-tree-root-node']/li/ul/li[@class='x-tree-node']/div/a/span[contains(text(), '{{name}}')]" parameterized="true"/> + <element name="lastCreatedCategory" type="block" selector=".x-tree-root-ct li li:last-child" /> + <element name="treeContainer" type="block" selector=".tree-holder" /> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetActionSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetActionSection.xml new file mode 100644 index 0000000000000..280c41ae4206e --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetActionSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminProductAttributeSetActionSection"> + <element name="save" type="button" selector="button[title='Save']" timeout="30"/> + <element name="reset" type="button" selector="button[title='Reset']" timeout="30"/> + <element name="back" type="button" selector="button[title='Back']" timeout="30"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetEditSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetEditSection.xml new file mode 100644 index 0000000000000..9a69761ee1550 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetEditSection.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminProductAttributeSetEditSection"> + <!-- Groups Column --> + <element name="groupTree" type="block" selector="#tree-div1"/> + <element name="attributeGroup" type="text" selector="//*[@id='tree-div1']//span[text()='{{groupName}}']" parameterized="true"/> + <element name="attributeGroupExtender" type="button" selector="//*[@id='tree-div1']//span[text()='{{groupName}}']" parameterized="true"/> + <element name="attributeGroupCollapsed" type="button" selector="//*[@id='tree-div1']//span[text()='{{groupName}}']/parent::*/parent::*[contains(@class, 'collapsed')]" parameterized="true"/> + <element name="assignedAttribute" type="text" selector="//*[@id='tree-div1']//span[text()='{{attributeName}}']" parameterized="true"/> + <element name="xThLineItemYthAttributeGroup" type="text" selector="//*[@id='tree-div1']/ul/div/li[{{y}}]//li[{{x}}]" parameterized="true"/> + <element name="xThLineItemAttributeGroup" type="text" selector="//*[@id='tree-div1']//span[text()='{{groupName}}']/parent::*/parent::*/parent::*//li[{{x}}]//a/span" parameterized="true"/> + <!-- Unassigned Attributes Column --> + <element name="unassignedAttributesTree" type="block" selector="#tree-div2"/> + <element name="unassignedAttribute" type="text" selector="//*[@id='tree-div2']//span[text()='{{attributeName}}']" parameterized="true"/> + <element name="xThLineItemUnassignedAttribute" type="text" selector="//*[@id='tree-div2']//li[{{x}}]//a/span" parameterized="true"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetGridSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetGridSection.xml index 30fbf870fa478..0df7cbc65d6c5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetGridSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetGridSection.xml @@ -9,6 +9,10 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="AdminProductAttributeSetGridSection"> + <element name="filter" type="input" selector="#setGrid_filter_set_name"/> + <element name="searchBtn" type="button" selector="#container button[title='Search']" timeout="30"/> + <element name="nthRow" type="block" selector="#setGrid_table tbody tr:nth-of-type({{var1}})" parameterized="true"/> <element name="AttributeSetName" type="text" selector="//td[contains(text(), '{{var1}}')]" parameterized="true"/> + <element name="addAttributeSetBtn" type="button" selector="button.add-set" timeout="30"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetSection.xml index 19e59d1cd22e6..2c99945b0989e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductAttributeSetSection.xml @@ -8,6 +8,16 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminProductAttributeSetSection"> + <element name="name" type="input" selector="#attribute_set_name"/> + <element name="basedOn" type="select" selector="#skeleton_set"/> + <element name="saveBtn" type="button" selector="button.save-attribute-set" timeout="30"/> + <element name="deleteBtn" type="button" selector="button[title='Delete']" timeout="30"/> + <element name="attribute" type="button" selector="//span[text()='{{var1}}']" parameterized="true"/> + <element name="addNewGroupBtn" type="button" selector="button.add" timeout="30"/> + <element name="newGroupName" type="input" selector="input[name='name']"/> + <element name="modalOk" type="button" selector="button.action-accept" timeout="30"/> + </section> <section name="AttributeSetSection"> <element name="Save" type="button" selector="button[title='Save']" /> </section> @@ -17,4 +27,8 @@ <section name="Group"> <element name="FolderName" type="text" selector="//span[text()='{{var1}}']" parameterized="true"/> </section> + <section name="ModifyAttributes"> + <!-- Parameter is the attribute name --> + <element name="nthExistingAttribute" type="select" selector="//*[text()='{{attributeName}}']/../..//select" parameterized="true"/> + </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductCategoryCreationSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductCategoryCreationSection.xml new file mode 100644 index 0000000000000..a4566115099ef --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductCategoryCreationSection.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminProductCategoryCreationSection"> + <element name="firstExampleProduct" type="button" selector=".data-row:nth-of-type(1)"/> + <element name="newCategory" type="button" selector="//button/span[text()='New Category']"/> + + <element name="nameInput" type="input" selector="input[name='name']"/> + + <element name="parentCategory" type="block" selector=".product_form_product_form_create_category_modal div[data-role='selected-option']"/> + <element name="parentSearch" type="input" selector="aside input[data-role='advanced-select-text']"/> + <element name="parentSearchResult" type="block" selector="aside .admin__action-multiselect-menu-inner"/> + <element name="createCategory" type="button" selector="#save"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductContentSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductContentSection.xml new file mode 100644 index 0000000000000..12a00ae8b3777 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductContentSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminProductContentSection"> + <element name="sectionHeader" type="button" selector="div[data-index='content']" timeout="30"/> + <element name="descriptionTextArea" type="textarea" selector="#product_form_description"/> + <element name="shortDescriptionTextArea" type="textarea" selector="#product_form_short_description"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductCustomizableOptionsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductCustomizableOptionsSection.xml index 702de0a8e1803..cb80dade856a7 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductCustomizableOptionsSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductCustomizableOptionsSection.xml @@ -29,5 +29,14 @@ <element name="clickSelectPriceType" type="select" selector="//span[text()='{{var1}}']/parent::div/parent::div/parent::div//tbody//tr[@data-repeat-index='{{var2}}']//span[text()='Price Type']/parent::label/parent::div//select" parameterized="true"/> <element name="checkboxUseDefaultTitle" type="checkbox" selector="//span[text()='Option Title']/parent::label/parent::div/div//input[@type='checkbox']"/> <element name="checkboxUseDefaultOption" type="checkbox" selector="//table[@data-index='values']//tbody//tr[@data-repeat-index='{{var1}}']//div[@class='admin__field-control']//input[@type='checkbox']" parameterized="true"/> + + <!-- Elements that make it easier to select the most recently added element --> + <element name="lastOptionTitle" type="input" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[contains(@class, '_required')]//input" /> + <element name="lastOptionTypeParent" type="block" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[contains(@class, 'admin__action-multiselect-text')]" /> + <!-- var 1 represents the option type that you want to select, i.e "radio buttons" --> + <element name="optionType" type="block" selector="//*[@data-index='custom_options']//label[text()='{{var1}}'][ancestor::*[contains(@class, '_active')]]" parameterized="true" /> + <element name="addValue" type="button" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[@data-action='add_new_row']" /> + <element name="valueTitle" type="input" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[contains(@class, 'admin__control-table')]//tbody/tr[last()]//*[@data-index='title']//input" /> + <element name="valuePrice" type="input" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[contains(@class, 'admin__control-table')]//tbody/tr[last()]//*[@data-index='price']//input" /> </section> </sections> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFiltersSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFiltersSection.xml index a2d9970e9a758..2ad371f7c51bc 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFiltersSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFiltersSection.xml @@ -13,5 +13,20 @@ <element name="nameInput" type="input" selector="input[name=name]"/> <element name="skuInput" type="input" selector="input[name=sku]"/> <element name="apply" type="button" selector="button[data-action=grid-filter-apply]" timeout="30"/> + <element name="filter" type="button" selector="//div[@class='data-grid-filters-action-wrap']/button" timeout="30"/> + <element name="typeDropDown" type="multiselect" selector="//select[@name='type_id']" timeout="30"/> + <element name="bundleOption" type="multiselect" selector="//select[@name='type_id']/option[4]" timeout="30"/> + <element name="applyFilters" type="button" selector="//button[@class='action-secondary']" timeout="30"/> + <element name="allCheckbox" type="checkbox" selector="//div[@data-role='grid-wrapper']//label[@data-bind='attr: {for: ko.uid}']" timeout="30"/> + <element name="actions" type="button" selector="//div[@class='action-select-wrap']/button" timeout="30"/> + <element name="changeStatus" type="multiselect" selector="//div[@class='action-menu-items']//li[2]" timeout="30"/> + <element name="delete" type="multiselect" selector="//div[@class='action-menu-items']//li[1]" timeout="30"/> + <element name="disable" type="multiselect" selector="//div[@class='action-menu-items']//ul[@class='action-submenu _active']//li[span='Disable']" timeout="30"/> + <element name="enable" type="multiselect" selector="//div[@class='action-menu-items']//ul[@class='action-submenu _active']//li[span='Enable']" timeout="30"/> + <element name="filtersClear" type="button" selector="//div[@class='admin__data-grid-header']//button[@data-action='grid-filter-reset']" timeout="30"/> + <element name="productType" type="text" selector="//tr[@data-repeat-index='{{var1}}']//td[5]//div[@class='data-grid-cell-content']" parameterized="true"/> + <element name="priceOfFirstRow" type="text" selector="//tr[@data-repeat-index='0']//div[contains(., '{{var1}}')]" parameterized="true"/> + <element name="AllProductsNotOfBundleType" type="text" selector="//td[5]/div[text() != 'Bundle Product']"/> + <element name="attributeSetOfFirstRow" type="text" selector="//tr[@data-repeat-index='0']//div[contains(., '{{var1}}')]" parameterized="true"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormSection.xml index fd0d9bcd3ce34..7c1c578d96997 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductFormSection.xml @@ -8,12 +8,17 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="AdminProductFormSection"> + <element name="attributeSet" type="select" selector="div[data-index='attribute_set_id'] .admin__field-control"/> + <element name="attributeSetFilter" type="input" selector="div[data-index='attribute_set_id'] .admin__field-control input" timeout="30"/> + <element name="attributeSetFilterResult" type="input" selector="div[data-index='attribute_set_id'] .action-menu-item._last" timeout="30"/> <element name="productName" type="input" selector=".admin__field[data-index=name] input"/> <element name="productSku" type="input" selector=".admin__field[data-index=sku] input"/> <element name="productStatus" type="checkbox" selector="input[name='product[status]']"/> <element name="enableProductLabel" type="checkbox" selector="input[name='product[status]']+label"/> <element name="productStatusUseDefault" type="checkbox" selector="input[name='use_default[status]']"/> + <element name="productNameUseDefault" type="checkbox" selector="input[name='use_default[name]']"/> <element name="productPrice" type="input" selector=".admin__field[data-index=price] input"/> + <element name="productTaxClassUseDefault" type="checkbox" selector="input[name='use_default[tax_class_id]']"/> <element name="advancedPricingLink" type="button" selector="button[data-index='advanced_pricing_button']"/> <element name="categoriesDropdown" type="multiselect" selector="div[data-index='category_ids']"/> <element name="productQuantity" type="input" selector=".admin__field[data-index=qty] input"/> @@ -33,6 +38,8 @@ <element name="productFormTabState" type="text" selector="//strong[@class='admin__collapsible-title']/span[contains(text(), '{{tabName}}')]/parent::*/parent::*[@data-state-collapsible='{{state}}']" parameterized="true"/> <element name="visibility" type="select" selector="//select[@name='product[visibility]']"/> <element name="visibilityUseDefault" type="checkbox" selector="//input[@name='use_default[visibility]']"/> + <element name="divByDataIndex" type="input" selector="div[data-index='{{var}}']" parameterized="true"/> + <element name="attributeLabelByText" type="text" selector="//*[@class='admin__field']//span[text()='{{attributeLabel}}']" parameterized="true"/> </section> <section name="ProductInWebsitesSection"> <element name="sectionHeader" type="button" selector="div[data-index='websites']" timeout="30"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductGridSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductGridSection.xml index e4f571f7f0d83..36cbd2ddde6ab 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductGridSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductGridSection.xml @@ -16,6 +16,7 @@ <element name="productGridRows" type="text" selector="table.data-grid tr.data-row"/> <element name="firstProductRow" type="text" selector="table.data-grid tr.data-row:first-of-type"/> <element name="productThumbnail" type="text" selector="table.data-grid tr:nth-child({{row}}) td.data-grid-thumbnail-cell > img" parameterized="true"/> + <element name="productThumbnailBySrc" type="text" selector="img.admin__control-thumbnail[src*='{{pattern}}']" parameterized="true"/> <element name="productGridCell" type="text" selector="//tr[{{row}}]//td[count(//div[@data-role='grid-wrapper']//tr//th[contains(., '{{column}}')]/preceding-sibling::th) +1 ]" parameterized="true"/> <element name="productGridHeaderCell" type="text" selector="//div[@data-role='grid-wrapper']//tr//th[contains(., '{{column}}')]" parameterized="true"/> <element name="multicheckDropdown" type="button" selector="div[data-role='grid-wrapper'] th.data-grid-multicheck-cell button.action-multicheck-toggle"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductImagesSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductImagesSection.xml index a9749ac677964..2133781df0575 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductImagesSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductImagesSection.xml @@ -14,5 +14,22 @@ <element name="imageUploadButton" type="button" selector="div.image div.fileinput-button"/> <element name="imageFile" type="text" selector="//*[@id='media_gallery_content']//img[contains(@src, '{{url}}')]" parameterized="true"/> <element name="removeImageButton" type="button" selector=".action-remove"/> + <element name="modalOkBtn" type="button" selector="button.action-primary.action-accept"/> + <element name="uploadProgressBar" type="text" selector=".uploader .file-row"/> + + <element name="nthProductImage" type="button" selector="#media_gallery_content > div:nth-child({{var}}) img.product-image" parameterized="true"/> + <element name="nthRemoveImageBtn" type="button" selector="#media_gallery_content > div:nth-child({{var}}) button.action-remove" parameterized="true"/> + + <element name="altText" type="textarea" selector="textarea[data-role='image-description']"/> + + <element name="roleBase" type="button" selector="//div[contains(@class, 'field-image-role')]//ul/li/label[normalize-space(.) = 'Base']"/> + <element name="roleSmall" type="button" selector="//div[contains(@class, 'field-image-role')]//ul/li/label[normalize-space(.) = 'Small']"/> + <element name="roleThumbnail" type="button" selector="//div[contains(@class, 'field-image-role')]//ul/li/label[normalize-space(.) = 'Thumbnail']"/> + <element name="roleSwatch" type="button" selector="//div[contains(@class, 'field-image-role')]//ul/li/label[normalize-space(.) = 'Swatch']"/> + + <element name="isBaseSelected" type="button" selector="//div[contains(@class, 'field-image-role')]//ul/li[contains(@class, 'selected')]/label[normalize-space(.) = 'Base']"/> + <element name="isSmallSelected" type="button" selector="//div[contains(@class, 'field-image-role')]//ul/li[contains(@class, 'selected')]/label[normalize-space(.) = 'Small']"/> + <element name="isThumbnailSelected" type="button" selector="//div[contains(@class, 'field-image-role')]//ul/li[contains(@class, 'selected')]/label[normalize-space(.) = 'Thumbnail']"/> + <element name="isSwatchSelected" type="button" selector="//div[contains(@class, 'field-image-role')]//ul/li[contains(@class, 'selected')]/label[normalize-space(.) = 'Swatch']"/> </section> </sections> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontCategoryProductSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontCategoryProductSection.xml index e736378ca8ca0..aaec0600f8bf7 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontCategoryProductSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontCategoryProductSection.xml @@ -17,7 +17,9 @@ <element name="ProductTitleByName" type="button" selector="//main//li//a[contains(text(), '{{var1}}')]" parameterized="true"/> <element name="ProductPriceByName" type="text" selector="//main//li[.//a[contains(text(), '{{var1}}')]]//span[@class='price']" parameterized="true"/> <element name="ProductImageByName" type="text" selector="//main//li[.//a[contains(text(), '{{var1}}')]]//img[@class='product-image-photo']" parameterized="true"/> + <element name="ProductImageBySrc" type="text" selector=".products-grid img[src*='{{pattern}}']" parameterized="true"/> <element name="ProductInfoByName" type="text" selector="//main//li[.//a[contains(text(), '{{var1}}')]]//div[@class='product-item-info']" parameterized="true"/> <element name="ProductAddToCompareByName" type="text" selector="//main//li[.//a[contains(text(), '{{var1}}')]]//a[contains(@class, 'tocompare')]" parameterized="true"/> + <element name="ProductImageByNameAndSrc" type="text" selector="//main//li[.//a[contains(text(), '{{var1}}')]]//img[contains(@src, '{{src}}')]" parameterized="true"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductInfoMainSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductInfoMainSection.xml index 5abc388a7d65d..a981f125c5e90 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductInfoMainSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductInfoMainSection.xml @@ -18,12 +18,20 @@ <element name="oldPrice" type="text" selector=".old-price"/> <element name="productStockStatus" type="text" selector=".stock[title=Availability]>span"/> <element name="productImage" type="text" selector="//*[@id='maincontent']//div[@class='gallery-placeholder']//img[@class='fotorama__img']"/> + <element name="productImageSrc" type="text" selector="//*[@id='maincontent']//div[@class='gallery-placeholder']//img[contains(@src, '{{src}}')]" parameterized="true"/> <element name="productDescription" type="text" selector="#description .value"/> <element name="productOptionFieldInput" type="input" selector="//*[@id='product-options-wrapper']//div[@class='fieldset']//label[contains(.,'{{var1}}')]/../div[@class='control']//input[@type='text']" parameterized="true"/> <element name="productOptionAreaInput" type="textarea" selector="//*[@id='product-options-wrapper']//div[@class='fieldset']//label[contains(.,'{{var1}}')]/../div[@class='control']//textarea" parameterized="true"/> <element name="productOptionFile" type="file" selector="//*[@id='product-options-wrapper']//div[@class='fieldset']//label[contains(.,'OptionFile')]/../div[@class='control']//input[@type='file']" parameterized="true"/> <element name="productOptionSelect" type="select" selector="//*[@id='product-options-wrapper']//div[@class='fieldset']//label[contains(.,'{{var1}}')]/../div[@class='control']//select" parameterized="true"/> + + + <!-- The parameter is the nth custom option that you want to get --> + <element name="nthCustomOption" type="block" selector="//*[@id='product-options-wrapper']/*[@class='fieldset']/*[contains(@class, 'field')][{{customOptionNum}}]" parameterized="true" /> + <!-- The 1st parameter is the nth custom option, the 2nd parameter is the nth value in the option --> + <element name="nthCustomOptionInput" type="radio" selector="//*[@id='product-options-wrapper']/*[@class='fieldset']/*[contains(@class, 'field')][{{customOptionNum}}]//*[contains(@class, 'admin__field-option')][{{customOptionValueNum}}]//input" parameterized="true" /> <element name="productOptionRadioButtonsCheckbox" type="checkbox" selector="//*[@id='product-options-wrapper']//div[@class='fieldset']//label[contains(.,'{{var1}}')]/../div[@class='control']//input[@price='{{var2}}']" parameterized="true"/> + <element name="productOptionDataMonth" type="date" selector="//*[@id='product-options-wrapper']//div[@class='fieldset']//legend[contains(.,'{{var1}}')]/../div[@class='control']//select[@data-calendar-role='month']" parameterized="true"/> <element name="productOptionDataDay" type="date" selector="//*[@id='product-options-wrapper']//div[@class='fieldset']//legend[contains(.,'{{var1}}')]/../div[@class='control']//select[@data-calendar-role='day']" parameterized="true"/> <element name="productOptionDataYear" type="date" selector="//*[@id='product-options-wrapper']//div[@class='fieldset']//legend[contains(.,'{{var1}}')]/../div[@class='control']//select[@data-calendar-role='year']" parameterized="true"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductMoreInformationSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductMoreInformationSection.xml new file mode 100644 index 0000000000000..e6269631274eb --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductMoreInformationSection.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="StorefrontProductMoreInformationSection"> + <element name="moreInformation" type="button" selector="#tab-label-additional-title" timeout="30"/> + <element name="moreInformationTextArea" type="textarea" selector="#additional"/> + <element name="attributeLabel" type="text" selector=".col.label"/> + <element name="attributeValue" type="text" selector=".col.data"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageForCategoryTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageForCategoryTest.xml index ba90296d12380..04e34871c8b73 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageForCategoryTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageForCategoryTest.xml @@ -43,6 +43,6 @@ <actionGroup ref="CheckCategoryOnStorefront" stepKey="CheckCategoryOnStorefront"> <argument name="categoryEntity" value="SimpleSubCategory"/> </actionGroup> - <seeElement selector="{{StorefrontCategoryMainSection.imageSource(ImageUpload.filename)}}" stepKey="seeImage"/> + <seeElement selector="{{StorefrontCategoryMainSection.imageSource(ProductImage.filename)}}" stepKey="seeImage"/> </test> </tests> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGCatalogTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGCatalogTest.xml index ed20d4026896d..43ce7e59ba621 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGCatalogTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGCatalogTest.xml @@ -14,7 +14,7 @@ <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4" /> </before> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Catalog"/> <stories value="MAGETWO-42041-Default WYSIWYG toolbar configuration with Magento Media Gallery"/> <group value="Catalog"/> <title value="Admin should be able to add image to WYSIWYG Editor on Catalog Page"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGProductTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGProductTest.xml index 1fc24f096b14a..e0582fff6c3c7 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGProductTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGProductTest.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddImageToWYSIWYGProductTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Catalog"/> <stories value="MAGETWO-42041-Default WYSIWYG toolbar configuration with Magento Media Gallery"/> <group value="Catalog"/> <title value="Admin should be able to add image to WYSIWYG Editor on Product Page"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAssignProductAttributeToAttributeSetTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAssignProductAttributeToAttributeSetTest.xml new file mode 100644 index 0000000000000..3615f4132ffb0 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAssignProductAttributeToAttributeSetTest.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminAssignProductAttributeToAttributeSetTest"> + <annotations> + <features value="Catalog"/> + <stories value="Add/Update attribute set"/> + <title value="Admin should be able to assign attributes to an attribute set"/> + <description value="Admin should be able to assign attributes to an attribute set"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-168"/> + <group value="Catalog"/> + </annotations> + <before> + <createData entity="productDropDownAttribute" stepKey="attribute"/> + + <createData entity="productAttributeOption1" stepKey="option1"> + <requiredEntity createDataKey="attribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="option2"> + <requiredEntity createDataKey="attribute"/> + </createData> + + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData createDataKey="attribute" stepKey="deleteAttribute"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!-- Go to default attribute set edit page --> + <amOnPage url="{{AdminProductAttributeSetEditPage.url}}/{{AddToDefaultSet.attributeSetId}}/" stepKey="onAttributeSetEdit"/> + <!-- Assert created attribute in unassigned section --> + <see userInput="$$attribute.attribute_code$$" selector="{{AdminProductAttributeSetEditSection.unassignedAttributesTree}}" stepKey="seeAttributeInUnassigned"/> + <!-- Assign attribute to a group --> + <actionGroup ref="AssignAttributeToGroup" stepKey="assignAttributeToGroup"> + <argument name="group" value="Product Details"/> + <argument name="attribute" value="$$attribute.attribute_code$$"/> + </actionGroup> + <!-- Assert attribute in a group --> + <see userInput="$$attribute.attribute_code$$" selector="{{AdminProductAttributeSetEditSection.groupTree}}" stepKey="seeAttributeInGroup"/> + <!-- Save attribute set --> + <actionGroup ref="SaveAttributeSet" stepKey="SaveAttributeSet"/> + <!-- Go to create new product page --> + <amOnPage url="{{AdminProductCreatePage.url(AddToDefaultSet.attributeSetId, 'simple')}}" stepKey="navigateToNewProduct"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <!-- Assert attribute can be used in product creation --> + <seeElement selector="{{AdminProductFormSection.attributeLabelByText($$attribute.attribute[frontend_labels][0][label]$$)}}" stepKey="seeLabel"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateCategoryFromProductPageTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateCategoryFromProductPageTest.xml new file mode 100644 index 0000000000000..7c81f4472e92a --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateCategoryFromProductPageTest.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminCreateCategoryFromProductPageTest"> + <annotations> + <features value="Catalog"/> + <stories value="Create/Edit Category in Admin"/> + <description value="Admin should be able to create category from the product page" /> + <severity value="AVERAGE"/> + <testCaseId value="MC-234"/> + <group value="Catalog"/> + </annotations> + <before> + <!-- Login as admin --> + <createData entity="SimpleTwo" stepKey="simpleProduct"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <!-- Delete the created category --> + <actionGroup ref="DeleteMostRecentCategory" stepKey="getRidOfCreatedCategory"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simpleProduct" stepKey="deleteProduct"/> + </after> + + <!-- Find the product that we just created using the product grid and go to its page--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage"/> + <waitForPageLoad stepKey="waitForAdminProductGridLoad"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> + <actionGroup ref="filterProductGridBySku" stepKey="findCreatedProduct"> + <argument name="product" value="SimpleTwo"/> + </actionGroup> + <waitForPageLoad stepKey="waitForFiltersToBeApplied"/> + <click selector="{{AdminProductGridSection.firstRow}}" stepKey="clickOnProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + + <!-- Fill out the form for the new category --> + <actionGroup ref="FillNewProductCategory" stepKey="FillNewProductCategory"> + <argument name="categoryName" value="{{_defaultCategory.name}}"/> + </actionGroup> + + <!-- Check that category was created --> + <actionGroup ref="CategoryPresent" stepKey="checkIfCategoryPresent"> + <argument name="categoryName" value="{{_defaultCategory.name}}"/> + </actionGroup> + + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateCategoryTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateCategoryTest.xml index bf867ad3016f0..2c39be3317545 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateCategoryTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateCategoryTest.xml @@ -10,10 +10,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateCategoryTest"> <annotations> - <features value="Category Creation"/> + <features value="Catalog"/> <stories value="Create a Category via the Admin"/> - <title value="You should be able to create a Category in the admin back-end."/> - <description value="You should be able to create a Category in the admin back-end."/> + <title value="Admin should be able to create a Category"/> + <description value="Admin should be able to create a Category"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-72102"/> <group value="category"/> @@ -39,10 +39,10 @@ </test> <test name="AdminConfigDefaultCategoryLayoutFromConfigurationSettingTest"> <annotations> - <features value="[CMS] WYSIWYG update MAGETWO-36659"/> + <features value="Catalog"/> <stories value="Default layout configuration MAGETWO-88793"/> - <title value="Admin are able to config default layout for Category Page from System Configuration"/> - <description value="Admin are able to select layout that will be applied by default to Category Page, so that he does not need to change it manually every time he create a page"/> + <title value="Admin should be able to configure the default layout for Category Page from System Configuration"/> + <description value="Admin should be able to configure the default layout for Category Page from System Configuration"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-89024"/> <group value="category"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateProductCustomAttributeSet.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateProductCustomAttributeSet.xml new file mode 100644 index 0000000000000..65e987461b982 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateProductCustomAttributeSet.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminCreateProductCustomAttributeSet"> + <annotations> + <features value="Catalog"/> + <stories value="Add/Update attribute set"/> + <title value="Admin should be able to create a simple product using a custom attribute set"/> + <description value="Admin should be able to create a simple product using a custom attribute set"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-244"/> + <group value="Catalog"/> + </annotations> + + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <!-- Delete the new attribute set --> + <amOnPage url="{{AdminProductAttributeSetGridPage.url}}" stepKey="goToAttributeSets"/> + <waitForPageLoad stepKey="wait1"/> + <fillField selector="{{AdminProductAttributeSetGridSection.filter}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="filterByName"/> + <click selector="{{AdminProductAttributeSetGridSection.searchBtn}}" stepKey="clickSearch"/> + <click selector="{{AdminProductAttributeSetGridSection.nthRow('1')}}" stepKey="clickFirstRow"/> + <waitForPageLoad stepKey="wait2"/> + <click selector="{{AdminProductAttributeSetSection.deleteBtn}}" stepKey="clickDelete"/> + <click selector="{{AdminProductAttributeSetSection.modalOk}}" stepKey="confirmDelete"/> + <waitForPageLoad stepKey="wait3"/> + + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + + <!-- Create a new attribute set --> + <amOnPage url="{{AdminProductAttributeSetGridPage.url}}" stepKey="goToAttributeSets"/> + <waitForPageLoad stepKey="wait1"/> + <click selector="{{AdminProductAttributeSetGridSection.addAttributeSetBtn}}" stepKey="clickAddAttributeSet"/> + <fillField selector="{{AdminProductAttributeSetSection.name}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="fillName"/> + <selectOption selector="{{AdminProductAttributeSetSection.basedOn}}" userInput="Default" stepKey="selectDefaultSet"/> + <click selector="{{AdminProductAttributeSetSection.saveBtn}}" stepKey="clickSave1"/> + <dragAndDrop selector1="{{AdminProductAttributeSetSection.attribute('meta_keyword')}}" selector2="{{AdminProductAttributeSetSection.attribute('manufacturer')}}" stepKey="unassign1"/> + <click selector="{{AdminProductAttributeSetSection.addNewGroupBtn}}" stepKey="clickAddNewGroup"/> + <fillField selector="{{AdminProductAttributeSetSection.newGroupName}}" userInput="TestGroupName" stepKey="fillNewGroupName"/> + <click selector="{{AdminProductAttributeSetSection.modalOk}}" stepKey="clickOkInModal"/> + <dragAndDrop selector1="{{AdminProductAttributeSetSection.attribute('manufacturer')}}" selector2="{{AdminProductAttributeSetSection.attribute('TestGroupName')}}" stepKey="assignManufacturer"/> + <click selector="{{AdminProductAttributeSetSection.saveBtn}}" stepKey="clickSave2"/> + + <!-- Go to new product page and see a default attribute --> + <amOnPage url="{{AdminProductCreatePage.url('4', 'simple')}}" stepKey="goToNewProductPage"/> + <waitForPageLoad stepKey="wait2"/> + <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="expandSEOSection"/> + <seeElementInDOM selector="{{AdminProductFormSection.divByDataIndex('meta_keyword')}}" stepKey="seeMetaKeyword"/> + <dontSeeElementInDOM selector="{{AdminProductFormSection.divByDataIndex('testgroupname')}}" stepKey="dontSeeTestGroupName"/> + + <!-- Switch from default attribute set to new attribute set --> + <!-- A scrollToTopOfPage is needed to hide the floating header --> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> + <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="searchForAttrSet"/> + <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + + <!-- See new attibute set --> + <seeElementInDOM selector="{{AdminProductFormSection.divByDataIndex('testgroupname')}}" stepKey="seeTestGroupName"/> + <dontSeeElementInDOM selector="{{AdminProductFormSection.divByDataIndex('meta_keyword')}}" stepKey="dontSeeMetaKeyword"/> + + <!-- Finish filling the new product page --> + <actionGroup ref="fillMainProductFormNoWeight" stepKey="fillSimpleProductMain"> + <argument name="product" value="_defaultProduct"/> + </actionGroup> + <actionGroup ref="saveProductForm" stepKey="saveSimpleProduct"/> + + <!-- Check the storefront --> + <amOnPage url="{{_defaultProduct.name}}.html" stepKey="goToProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <seeInTitle userInput="{{_defaultProduct.name}}" stepKey="seeProductNameInTitlte"/> + <see userInput="{{_defaultProduct.name}}" selector="{{StorefrontProductInfoMainSection.productName}}" stepKey="assertProductName"/> + <see userInput="{{_defaultProduct.sku}}" selector="{{StorefrontProductInfoMainSection.productSku}}" stepKey="assertProductSku"/> + <see userInput="${{_defaultProduct.price}}" selector="{{StorefrontProductInfoMainSection.productPrice}}" stepKey="assertProductPrice"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateProductDuplicateUrlkeyTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateProductDuplicateUrlkeyTest.xml index bb5583f0c3d1a..4e3f9da79b643 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateProductDuplicateUrlkeyTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateProductDuplicateUrlkeyTest.xml @@ -10,10 +10,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateProductDuplicateUrlkeyTest"> <annotations> - <features value="Product Creation Negative"/> - <stories value="Error when try to save project with duplicate URL key"/> - <title value="Error when try to save project with duplicate URL key."/> - <description value="Error when try to save project with duplicate URL key."/> + <features value="Catalog"/> + <stories value="Errors"/> + <title value="Admin should see an error when trying to save a product with a duplicate URL key"/> + <description value="Admin should see an error when trying to save a product with a duplicate URL key"/> <severity value="MAJOR"/> <testCaseId value="MC-112"/> <group value="product"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateRootCategoryAndSubcategoriesTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateRootCategoryAndSubcategoriesTest.xml index 8495736b52e18..791ed1fdf83ac 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateRootCategoryAndSubcategoriesTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateRootCategoryAndSubcategoriesTest.xml @@ -10,9 +10,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateRootCategoryAndSubcategoriesTest"> <annotations> - <features value="Create Root Category and Subcategory"/> - <title value="You should be able to create Root Category and Subcategory."/> - <description value="You should be able to create Root Category and Subcategory."/> + <features value="Catalog"/> + <title value="Admin should be able to create a Root Category and a Subcategory"/> + <description value="Admin should be able to create a Root Category and a Subcategory"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-46142"/> <group value="category"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateSimpleProductTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateSimpleProductTest.xml index 250e1c88fd0f1..f5fb0e87bdc01 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateSimpleProductTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateSimpleProductTest.xml @@ -10,10 +10,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateSimpleProductTest"> <annotations> - <features value="Product Creation"/> + <features value="Catalog"/> <stories value="Create a Simple Product via Admin"/> - <title value="You should be able to create a Simple Product in the admin back-end."/> - <description value="You should be able to create a Simple Product in the admin back-end."/> + <title value="Admin should be able to create a Simple Product"/> + <description value="Admin should be able to create a Simple Product"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-23414"/> <group value="product"/> @@ -42,10 +42,10 @@ <test name="AdminConfigDefaultProductLayoutFromConfigurationSettingTest"> <annotations> - <features value="[CMS] WYSIWYG update MAGETWO-36659"/> + <features value="Catalog"/> <stories value="Default layout configuration MAGETWO-88793"/> - <title value="Admin are able to config default layout for Product Page from System Configuration"/> - <description value="Admin are able to select layout that will be applied by default to Product Page, so that he does not need to change it manually every time he create a page"/> + <title value="Admin should be able to configure a default layout for Product Page from System Configuration"/> + <description value="Admin should be able to configure a default layout for Product Page from System Configuration"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-89023"/> <group value="product"/> @@ -72,10 +72,10 @@ <test name="AdminCreateSimpleProductZeroPriceTest"> <annotations> - <features value="Product Creation"/> + <features value="Catalog"/> <stories value="Create a Simple Product via Admin"/> - <title value="Should be able to create a product with zero price"/> - <description value="Should be able to create a product with zero price"/> + <title value="Admin should be able to create a product with zero price"/> + <description value="Admin should be able to create a product with zero price"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-89910"/> <group value="product"/> @@ -93,10 +93,10 @@ <test name="AdminCreateSimpleProductNegativePriceTest"> <annotations> - <features value="Product Creation"/> + <features value="Catalog"/> <stories value="Create a Simple Product via Admin"/> - <title value="Should not be able to create a product with a negative price"/> - <description value="Should not be able to create a product with a negative price"/> + <title value="Admin should not be able to create a product with a negative price"/> + <description value="Admin should not be able to create a product with a negative price"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-89912"/> <group value="product"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateSimpleProductWithUnicodeTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateSimpleProductWithUnicodeTest.xml index ace6cf7198fc4..db127799c97e9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateSimpleProductWithUnicodeTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminCreateSimpleProductWithUnicodeTest.xml @@ -10,10 +10,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateSimpleProductWithUnicodeTest"> <annotations> - <features value="Product Creation"/> + <features value="Catalog"/> <stories value="Create a Unicode Named Simple Product via Admin"/> - <title value="You should be able to create a unicode named simple product in admin."/> - <description value="You should be able to create a unicode named simple product in admin."/> + <title value="Admin should be able to create a unicode named simple product"/> + <description value="Admin should be able to create a unicode named simple product"/> <severity value="MAJOR" /> <testCaseId value="MC-105"/> <group value="product"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminEditTextEditorProductAttributeTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminEditTextEditorProductAttributeTest.xml index 7b0135973e211..d406b6c920dc0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminEditTextEditorProductAttributeTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminEditTextEditorProductAttributeTest.xml @@ -9,11 +9,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminEditTextEditorProductAttributeTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Catalog"/> <stories value="MAGETWO-51484-Input type configuration for custom Product Attributes"/> <group value="Catalog"/> - <title value="Admin see TinyMCEv4.6 is native WYSIWYG on Product Page"/> - <description value="Admin should be able to switch between 2 version of Tinymce in the admin back-end."/> + <title value="Admin should be able to switch between two versions of TinyMCE"/> + <description value="Admin should be able to switch between two versions of TinyMCE"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-85745"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminMoveAnchoredCategoryTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminMoveAnchoredCategoryTest.xml index ecdcd7fcfebeb..024af2a77a5ef 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminMoveAnchoredCategoryTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminMoveAnchoredCategoryTest.xml @@ -9,9 +9,9 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminMoveAnchoredCategoryTest"> <annotations> - <features value="Category Moving"/> - <title value="Move Anchored Category with Products"/> - <description value="You should be able to move a category via categories tree and made changes should be applied on frontend without forced cache cleaning"/> + <features value="Catalog"/> + <title value="Admin should be able to move a category via categories tree and changes should be applied on frontend without a forced cache cleaning"/> + <description value="Admin should be able to move a category via categories tree and changes should be applied on frontend without a forced cache cleaning"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-76273"/> <group value="category"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminMultipleWebsitesUseDefaultValuesTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminMultipleWebsitesUseDefaultValuesTest.xml new file mode 100644 index 0000000000000..1b4d9372cb509 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminMultipleWebsitesUseDefaultValuesTest.xml @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminMultipleWebsitesUseDefaultValuesTest"> + <annotations> + <title value="Use Default Value checkboxes should be checked for new website scope"/> + <description value="Use Default Value checkboxes for product attribute should be checked for new website scope"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-92454"/> + <group value="Catalog"/> + </annotations> + <after> + <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteSecondWebsite"> + <argument name="websiteName" value="Second Website"/> + </actionGroup> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createAdditionalWebsite"> + <argument name="newWebsiteName" value="Second Website"/> + <argument name="websiteCode" value="second_website"/> + </actionGroup> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createNewStore"> + <argument name="website" value="Second Website"/> + <argument name="storeGroupName" value="Second Store"/> + <argument name="storeGroupCode" value="second_store"/> + </actionGroup> + + <!--Create Store view --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="amOnAdminSystemStorePage"/> + <click selector="{{AdminStoresMainActionsSection.createStoreViewButton}}" stepKey="createStoreViewButton"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <selectOption userInput="Second Store" selector="{{AdminNewStoreSection.storeGrpDropdown}}" stepKey="selectStoreGroup"/> + <fillField userInput="Second Store View" selector="{{AdminNewStoreSection.storeNameTextField}}" stepKey="fillStoreViewName"/> + <fillField userInput="second_store_view" selector="{{AdminNewStoreSection.storeCodeTextField}}" stepKey="fillStoreViewCode"/> + <selectOption selector="{{AdminNewStoreSection.statusDropdown}}" userInput="1" stepKey="enableStoreViewStatus"/> + <click selector="{{AdminStoresMainActionsSection.saveButton}}" stepKey="clickStoreViewSaveButton"/> + <waitForElementVisible selector="{{AdminNewStoreSection.acceptNewStoreViewCreation}}" stepKey="waitForAcceptNewStoreViewCreationModal" /> + <conditionalClick selector="{{AdminNewStoreSection.acceptNewStoreViewCreation}}" dependentSelector="{{AdminNewStoreSection.acceptNewStoreViewCreation}}" visible="true" stepKey="AcceptNewStoreViewCreation"/> + <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" stepKey="waitForPageReload"/> + <see userInput="You saved the store view." stepKey="seeSaveMessage"/> + + <!--Create a Simple Product --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToCatalogProductGrid"/> + <click selector="{{AdminProductGridActionSection.addProductToggle}}" stepKey="clickAddProductDropdown"/> + <click selector="{{AdminProductGridActionSection.addSimpleProduct}}" stepKey="clickAddSimpleProduct"/> + <fillField userInput="{{_defaultProduct.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="fillProductName"/> + <fillField userInput="{{_defaultProduct.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillProductSKU"/> + <fillField userInput="{{_defaultProduct.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillProductPrice"/> + <fillField userInput="{{_defaultProduct.quantity}}" selector="{{AdminProductFormSection.productQuantity}}" stepKey="fillProductQuantity"/> + + <!-- Add product to second website and save the product --> + <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="openProductInWebsites"/> + <click selector="{{ProductInWebsitesSection.website('Second Website')}}" stepKey="selectSecondWebsite"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSave"/> + <waitForLoadingMaskToDisappear stepKey="waitForProductPageSave"/> + <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="seeSaveProductMessage"/> + + <!-- switch to the second store view --> + <click selector="{{AdminProductFormActionSection.changeStoreButton}}" stepKey="clickStoreviewSwitcher"/> + <click selector="{{AdminProductFormActionSection.selectStoreView('Second Store View')}}" stepKey="chooseStoreView"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="acceptStoreSwitchingMessage"/> + <!--<waitForPageLoad stepKey="waitForStoreViewSwitched"/>--> + <waitForPageLoad time="30" stepKey="waitForPageLoad9"/> + <see userInput="Second Store View" selector="{{AdminMainActionsSection.storeSwitcher}}" stepKey="seeNewStoreViewName"/> + + <!-- Check if Use Default Value checkboxes are checked --> + <seeCheckboxIsChecked selector="{{AdminProductFormSection.productStatusUseDefault}}" stepKey="seeProductStatusCheckboxChecked"/> + <seeCheckboxIsChecked selector="{{AdminProductFormSection.productNameUseDefault}}" stepKey="seeProductNameCheckboxChecked"/> + <seeCheckboxIsChecked selector="{{AdminProductFormSection.productTaxClassUseDefault}}" stepKey="seeTaxClassCheckboxChecked"/> + <seeCheckboxIsChecked selector="{{AdminProductFormSection.visibilityUseDefault}}" stepKey="seeVisibilityCheckboxChecked"/> + </test> +</tests> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminSimpleProductImagesTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminSimpleProductImagesTest.xml new file mode 100644 index 0000000000000..d0d5ba4a6f7ba --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminSimpleProductImagesTest.xml @@ -0,0 +1,304 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminSimpleProductImagesTest"> + <annotations> + <features value="Catalog"/> + <stories value="Add/remove images and videos for all product types and category"/> + <title value="Admin should be able to add images of different types and sizes to Simple Product"/> + <description value="Admin should be able to add images of different types and sizes to Simple Product"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-189"/> + <group value="Catalog"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="category"/> + <createData entity="_defaultProduct" stepKey="firstProduct"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="_defaultProduct" stepKey="secondProduct"> + <requiredEntity createDataKey="category"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <deleteData createDataKey="category" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="firstProduct" stepKey="deleteFirstProduct"/> + <deleteData createDataKey="secondProduct" stepKey="deleteSecondProduct"/> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + + <!-- Go to the first product edit page --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex"/> + <waitForPageLoad stepKey="wait1"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetProductGrid"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterProductGridBySku"> + <argument name="product" value="$$firstProduct$$"/> + </actionGroup> + <actionGroup ref="openProducForEditByClickingRowXColumnYInProductGrid" stepKey="openProducForEditByClickingRow1Column2InProductGrid"/> + + <!-- Set url key --> + <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection"/> + <fillField selector="{{AdminProductSEOSection.urlKeyInput}}" userInput="$$firstProduct.name$$" stepKey="fillUrlKey"/> + + <click selector="{{AdminProductImagesSection.productImagesToggle}}" stepKey="expandImages"/> + + <!-- *.bmp is not allowed --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="bmp.bmp" stepKey="attachBmp"/> + <waitForPageLoad stepKey="waitForUploadBmp"/> + <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="bmp.bmp was not uploaded. Disallowed file type." stepKey="seeErrorBmp"/> + <click selector="{{AdminProductImagesSection.modalOkBtn}}" stepKey="closeModalBmp"/> + + <!-- *.ico is not allowed --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="ico.ico" stepKey="attachIco"/> + <waitForPageLoad stepKey="waitForUploadIco"/> + <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="ico.ico was not uploaded. Disallowed file type." stepKey="seeErrorIco"/> + <click selector="{{AdminProductImagesSection.modalOkBtn}}" stepKey="closeModalIco"/> + + <!-- *.svg is not allowed --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="svg.svg" stepKey="attachSvg"/> + <waitForPageLoad stepKey="waitForUploadSvg"/> + <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="svg.svg was not uploaded. Disallowed file type." stepKey="seeErrorSvg"/> + <click selector="{{AdminProductImagesSection.modalOkBtn}}" stepKey="closeModalSvg"/> + + <!-- 0kb size is not allowed --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="empty.jpg" stepKey="attachEmpty"/> + <waitForPageLoad stepKey="waitForUploadEmpty"/> + <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="empty.jpg was not uploaded." stepKey="seeErrorEmpty"/> + <click selector="{{AdminProductImagesSection.modalOkBtn}}" stepKey="closeModalEmpty"/> + + <!-- 1~ kb is allowed --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="small.jpg" stepKey="attachSmall"/> + <waitForPageLoad stepKey="waitForUploadSmall"/> + <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorSmall"/> + + <!-- 1~ mb is allowed --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="medium.jpg" stepKey="attachMedium"/> + <waitForPageLoad stepKey="waitForUploadMedium"/> + <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorMedium"/> + + <!-- 10~ mb is allowed --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="large.jpg" stepKey="attachLarge"/> + <waitForPageLoad stepKey="waitForUploadLarge"/> + <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorLarge"/> + + <!-- *.gif is allowed --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="gif.gif" stepKey="attachGif"/> + <waitForPageLoad stepKey="waitForUploadGif"/> + <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorGif"/> + + <!-- *.jpg is allowed --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="jpg.jpg" stepKey="attachJpg"/> + <waitForPageLoad stepKey="waitForUploadJpg"/> + <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorJpg"/> + + <!-- *.png is allowed --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="png.png" stepKey="attachPng"/> + <waitForPageLoad stepKey="waitForUploadPng"/> + <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorPng"/> + + <!-- Save the first product and go to the storefront --> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> + <amOnPage url="$$firstProduct.name$$.html" stepKey="goToStorefront"/> + <waitForPageLoad stepKey="waitForStorefront"/> + + <!-- See all of the images that we uploaded --> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('small')}}" stepKey="seeSmall"/> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('medium')}}" stepKey="seeMedium"/> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('large')}}" stepKey="seeLarge"/> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('gif')}}" stepKey="seeGif"/> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('jpg')}}" stepKey="seeJpg"/> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('png')}}" stepKey="seePng"/> + + <!-- Go to the category page and see a placeholder image for the second product --> + <amOnPage url="$$category.name$$.html" stepKey="goToCategoryPage"/> + <seeElement selector=".products-grid img[src*='placeholder/small_image.jpg']" stepKey="seePlaceholder"/> + + <!-- Go to the second product edit page --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex2"/> + <waitForPageLoad stepKey="wait2"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetProductGrid2"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterProductGridBySku2"> + <argument name="product" value="$$secondProduct$$"/> + </actionGroup> + <actionGroup ref="openProducForEditByClickingRowXColumnYInProductGrid" stepKey="openProducForEditByClickingRow1Column2InProductGrid2"/> + + <!-- Upload an image --> + <click selector="{{AdminProductImagesSection.productImagesToggle}}" stepKey="expandImages2"/> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="large.jpg" stepKey="attachLarge2"/> + <waitForPageLoad stepKey="waitForUploadLarge2"/> + <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorLarge2"/> + + <!-- Set url key --> + <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection2"/> + <fillField selector="{{AdminProductSEOSection.urlKeyInput}}" userInput="$$secondProduct.name$$" stepKey="fillUrlKey2"/> + + <!-- Save the second product --> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct2"/> + + <!-- Go to the admin grid and see the uploaded image --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex3"/> + <waitForPageLoad stepKey="wait3"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetProductGrid3"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterProductGridBySku3"> + <argument name="product" value="$$secondProduct$$"/> + </actionGroup> + <seeElement selector="img.admin__control-thumbnail[src*='/large']" stepKey="seeImgInGrid"/> + + <!-- Go to the category page and see the uploaded image --> + <amOnPage url="$$category.name$$.html" stepKey="goToCategoryPage2"/> + <seeElement selector=".products-grid img[src*='/large']" stepKey="seeUploadedImg"/> + + <!-- Go to the product page and see the uploaded image --> + <amOnPage url="$$secondProduct.name$$.html" stepKey="goToStorefront2"/> + <waitForPageLoad stepKey="waitForStorefront2"/> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('large')}}" stepKey="seeLarge2"/> + </test> + + <test name="AdminSimpleProductRemoveImagesTest"> + <annotations> + <features value="Catalog"/> + <stories value="Add/remove images and videos for all product types and category"/> + <title value="Admin should be able to remove Product Images assigned as Base, Small and Thumbnail from Simple Product"/> + <description value="Admin should be able to remove Product Images assigned as Base, Small and Thumbnail from Simple Product"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-191"/> + <group value="Catalog"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="category"/> + <createData entity="_defaultProduct" stepKey="product"> + <requiredEntity createDataKey="category"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <deleteData createDataKey="category" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="product" stepKey="deleteProduct"/> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + + <!-- Go to the product edit page --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex"/> + <waitForPageLoad stepKey="wait1"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetProductGrid"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterProductGridBySku"> + <argument name="product" value="$$product$$"/> + </actionGroup> + <actionGroup ref="openProducForEditByClickingRowXColumnYInProductGrid" stepKey="openProduct"/> + + <!-- Set url key --> + <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection"/> + <fillField selector="{{AdminProductSEOSection.urlKeyInput}}" userInput="$$product.name$$" stepKey="fillUrlKey"/> + + <!-- Expand images section --> + <click selector="{{AdminProductImagesSection.productImagesToggle}}" stepKey="expandImages"/> + + <!-- Upload and set Base image --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="adobe-base.jpg" stepKey="attach1"/> + <waitForPageLoad stepKey="waitForUpload1"/> + <click selector="{{AdminProductImagesSection.nthProductImage('1')}}" stepKey="openImageDetails1"/> + <waitForPageLoad stepKey="waitForSlideout1"/> + <conditionalClick selector="{{AdminProductImagesSection.roleBase}}" dependentSelector="{{AdminProductImagesSection.isBaseSelected}}" visible="false" stepKey="base1"/> + <conditionalClick selector="{{AdminProductImagesSection.roleSmall}}" dependentSelector="{{AdminProductImagesSection.isSmallSelected}}" visible="true" stepKey="small1"/> + <conditionalClick selector="{{AdminProductImagesSection.roleThumbnail}}" dependentSelector="{{AdminProductImagesSection.isThumbnailSelected}}" visible="true" stepKey="thumbnail1"/> + <conditionalClick selector="{{AdminProductImagesSection.roleSwatch}}" dependentSelector="{{AdminProductImagesSection.isSwatchSelected}}" visible="true" stepKey="swatch1"/> + <pressKey selector="{{AdminProductImagesSection.altText}}" parameterArray="[\Facebook\WebDriver\WebDriverKeys::ESCAPE]" stepKey="pressEsc1"/> + <waitForPageLoad stepKey="waitForHide1"/> + + <!-- Upload and set Small image --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="adobe-small.jpg" stepKey="attach2"/> + <waitForPageLoad stepKey="waitForUpload2"/> + <click selector="{{AdminProductImagesSection.nthProductImage('2')}}" stepKey="openImageDetails2"/> + <waitForPageLoad stepKey="waitForSlideout2"/> + <conditionalClick selector="{{AdminProductImagesSection.roleBase}}" dependentSelector="{{AdminProductImagesSection.isBaseSelected}}" visible="true" stepKey="base2"/> + <conditionalClick selector="{{AdminProductImagesSection.roleSmall}}" dependentSelector="{{AdminProductImagesSection.isSmallSelected}}" visible="false" stepKey="small2"/> + <conditionalClick selector="{{AdminProductImagesSection.roleThumbnail}}" dependentSelector="{{AdminProductImagesSection.isThumbnailSelected}}" visible="true" stepKey="thumbnail2"/> + <conditionalClick selector="{{AdminProductImagesSection.roleSwatch}}" dependentSelector="{{AdminProductImagesSection.isSwatchSelected}}" visible="true" stepKey="swatch2"/> + <pressKey selector="{{AdminProductImagesSection.altText}}" parameterArray="[\Facebook\WebDriver\WebDriverKeys::ESCAPE]" stepKey="pressEsc2"/> + <waitForPageLoad stepKey="waitForHide2"/> + + <!-- Upload and set Thumbnail image --> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="adobe-thumb.jpg" stepKey="attach3"/> + <waitForPageLoad stepKey="waitForUpload3"/> + <click selector="{{AdminProductImagesSection.nthProductImage('3')}}" stepKey="openImageDetails3"/> + <waitForPageLoad stepKey="waitForSlideout3"/> + <conditionalClick selector="{{AdminProductImagesSection.roleBase}}" dependentSelector="{{AdminProductImagesSection.isBaseSelected}}" visible="true" stepKey="base3"/> + <conditionalClick selector="{{AdminProductImagesSection.roleSmall}}" dependentSelector="{{AdminProductImagesSection.isSmallSelected}}" visible="true" stepKey="small3"/> + <conditionalClick selector="{{AdminProductImagesSection.roleThumbnail}}" dependentSelector="{{AdminProductImagesSection.isThumbnailSelected}}" visible="false" stepKey="thumbnail3"/> + <conditionalClick selector="{{AdminProductImagesSection.roleSwatch}}" dependentSelector="{{AdminProductImagesSection.isSwatchSelected}}" visible="true" stepKey="swatch3"/> + <pressKey selector="{{AdminProductImagesSection.altText}}" parameterArray="[\Facebook\WebDriver\WebDriverKeys::ESCAPE]" stepKey="pressEsc3"/> + <waitForPageLoad stepKey="waitForHide3"/> + + <!-- Save the product with all 3 images --> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> + + <!-- Go to the product page and see the Base image --> + <amOnPage url="$$product.name$$.html" stepKey="goToProductPage"/> + <waitForPageLoad stepKey="wait4"/> + <seeElement selector="{{StorefrontProductMediaSection.imageFile('/adobe-base')}}" stepKey="seeBase"/> + + <!-- Go to the category page and see the Small image --> + <amOnPage url="$$category.name$$.html" stepKey="goToCategoryPage"/> + <waitForPageLoad stepKey="wait3"/> + <seeElement selector="{{StorefrontCategoryProductSection.ProductImageBySrc('/adobe-small')}}" stepKey="seeThumb"/> + + <!-- Go to the admin grid and see the Thumbnail image --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex2"/> + <waitForPageLoad stepKey="wait2"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetProductGrid2"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterProductGridBySku2"> + <argument name="product" value="$$product$$"/> + </actionGroup> + <seeElement selector="{{AdminProductGridSection.productThumbnailBySrc('/adobe-thumb')}}" stepKey="seeBaseInGrid"/> + + <!-- Go to the product edit page again --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex3"/> + <waitForPageLoad stepKey="wait5"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetProductGrid3"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterProductGridBySku3"> + <argument name="product" value="$$product$$"/> + </actionGroup> + <actionGroup ref="openProducForEditByClickingRowXColumnYInProductGrid" stepKey="openProduct3"/> + <click selector="{{AdminProductImagesSection.productImagesToggle}}" stepKey="expandImages2"/> + + <!-- Remove all images --> + <click selector="{{AdminProductImagesSection.nthRemoveImageBtn('1')}}" stepKey="removeImage1"/> + <click selector="{{AdminProductImagesSection.nthRemoveImageBtn('2')}}" stepKey="removeImage2"/> + <click selector="{{AdminProductImagesSection.nthRemoveImageBtn('3')}}" stepKey="removeImage3"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct2"/> + + <!-- Check admin grid for placeholder --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex4"/> + <waitForPageLoad stepKey="wait6"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetProductGrid4"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterProductGridBySku4"> + <argument name="product" value="$$product$$"/> + </actionGroup> + <dontSeeElement selector="{{AdminProductGridSection.productThumbnailBySrc('/adobe-thumb')}}" stepKey="dontSeeBaseInGrid"/> + <seeElement selector="{{AdminProductGridSection.productThumbnailBySrc('/placeholder/thumbnail')}}" stepKey="seePlaceholderThumb"/> + + <!-- Check category page for placeholder --> + <amOnPage url="$$category.name$$.html" stepKey="goToCategoryPage2"/> + <waitForPageLoad stepKey="wait7"/> + <dontSeeElement selector="{{StorefrontCategoryProductSection.ProductImageBySrc('/adobe-small')}}" stepKey="dontSeeThumb"/> + <seeElement selector="{{StorefrontCategoryProductSection.ProductImageBySrc('placeholder/small_image')}}" stepKey="seePlaceholderSmall"/> + + <!-- Check product page for placeholder --> + <amOnPage url="$$product.name$$.html" stepKey="goToProductPage2"/> + <waitForPageLoad stepKey="wait8"/> + <dontSeeElement selector="{{StorefrontProductMediaSection.imageFile('/adobe-base')}}" stepKey="dontSeeBase"/> + <seeElement selector="{{StorefrontProductMediaSection.imageFile('placeholder/image')}}" stepKey="seePlaceholderBase"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminUnassignProductAttributeFromAttributeSetTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminUnassignProductAttributeFromAttributeSetTest.xml new file mode 100644 index 0000000000000..7be5e5d281933 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminUnassignProductAttributeFromAttributeSetTest.xml @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminUnassignProductAttributeFromAttributeSetTest"> + <annotations> + <features value="Catalog"/> + <stories value="Add/Update attribute set"/> + <title value="Admin should be able to unassign attributes from an attribute set"/> + <description value="Admin should be able to unassign attributes from an attribute set"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-194"/> + <group value="Catalog"/> + <!-- Skip because of MAGETWO-92780 --> + <group value="skip"/> + </annotations> + <before> + <createData entity="productDropDownAttribute" stepKey="attribute"/> + + <createData entity="productAttributeOption1" stepKey="option1"> + <requiredEntity createDataKey="attribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="option2"> + <requiredEntity createDataKey="attribute"/> + </createData> + + <createData entity="AddToDefaultSet" stepKey="addToDefaultSet"> + <requiredEntity createDataKey="attribute"/> + </createData> + + <createData entity="ApiProductWithDescription" stepKey="product"/> + + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData createDataKey="attribute" stepKey="deleteAttribute"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!-- Assert attribute presence in storefront product additional information --> + <amOnPage url="/$$product.custom_attributes[url_key]$$.html" stepKey="onProductPage1"/> + <waitForPageLoad stepKey="wait1"/> + <actionGroup ref="checkAttributeInMoreInformationTab" stepKey="checkAttributeInMoreInformationTab"> + <argument name="attributeLabel" value="$$attribute.attribute[frontend_labels][0][label]$$"/> + <argument name="attributeValue" value="$$option2.option[store_labels][0][label]$$"/> + </actionGroup> + <!-- Go to default attribute set edit page --> + <amOnPage url="{{AdminProductAttributeSetEditPage.url}}/{{AddToDefaultSet.attributeSetId}}/" stepKey="onAttributeSetEdit"/> + <!-- Assert created attribute in a group --> + <see userInput="$$attribute.attribute_code$$" selector="{{AdminProductAttributeSetEditSection.groupTree}}" stepKey="seeAttributeInGroup"/> + <!-- Unassign attribute from group --> + <actionGroup ref="UnassignAttributeFromGroup" stepKey="UnassignAttributeFromGroup"> + <argument name="group" value="Product Details"/> + <argument name="attribute" value="$$attribute.attribute_code$$"/> + </actionGroup> + <!-- Assert attribute in unassigned section --> + <see userInput="$$attribute.attribute_code$$" selector="{{AdminProductAttributeSetEditSection.unassignedAttributesTree}}" stepKey="seeAttributeInUnassigned"/> + <!-- Save attribute set --> + <actionGroup ref="SaveAttributeSet" stepKey="SaveAttributeSet"/> + <!-- Go to create new product page --> + <amOnPage url="{{AdminProductCreatePage.url(AddToDefaultSet.attributeSetId, 'simple')}}" stepKey="navigateToNewProduct"/> + <waitForPageLoad stepKey="wait2"/> + <!-- Assert attribute not present in product creation --> + <dontSeeElement selector="{{AdminProductFormSection.attributeLabelByText($$attribute.attribute[frontend_labels][0][label]$$)}}" stepKey="seeLabel"/> + <!-- Assert removed attribute not presence in storefront product additional information --> + <amOnPage url="/$$product.custom_attributes[url_key]$$.html" stepKey="onProductPage2"/> + <waitForPageLoad stepKey="wait3"/> + <actionGroup ref="checkAttributeNotInMoreInformationTab" stepKey="checkAttributeNotInMoreInformationTab"> + <argument name="attributeLabel" value="$$attribute.attribute[frontend_labels][0][label]$$"/> + </actionGroup> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminUpdateCategoryStoreUrlKeyTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminUpdateCategoryStoreUrlKeyTest.xml new file mode 100644 index 0000000000000..e29890befd860 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminUpdateCategoryStoreUrlKeyTest.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminUpdateCategoryStoreUrlKeyTest"> + <annotations> + <features value="SEO-friendly URL Key Update"/> + <stories value="Update SEO-friendly URL via the Admin"/> + <title value="SEO-friendly URL should update regardless of scope or redirect change."/> + <description value="SEO-friendly URL should update regardless of scope or redirect change."/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-92338"/> + <group value="category"/> + </annotations> + <after> + <actionGroup ref="DeleteCategory" stepKey="deleteCategory"> + <argument name="categoryEntity" value="_defaultCategory"/> + </actionGroup> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + + <!-- Create category, change store view to default --> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <actionGroup ref="CreateCategory" stepKey="createCategory"> + <argument name="categoryEntity" value="_defaultCategory"/> + </actionGroup> + + <!--Switch to "Default Store View" scope--> + <actionGroup ref="switchCategoryStoreView" stepKey="SwitchStoreView"> + <argument name="Store" value="_defaultStore.name"/> + <argument name="CatName" value="_defaultCategory.name"/> + </actionGroup> + <!--See "Use Default Value" checkboxes--> + <seeElement selector="{{AdminCategoryBasicFieldSection.enableUseDefault}}" stepKey="seeUseDefaultEnable"/> + <seeElement selector="{{AdminCategoryBasicFieldSection.includeInMenuUseDefault}}" stepKey="seeUseDefaultMenu"/> + <seeElement selector="{{AdminCategoryBasicFieldSection.categoryNameUseDefault}}" stepKey="seeUseDefaultName"/> + <!-- Update SEO key, uncheck "Create Redirect", confirm in frontend --> + <click selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="openSeoSection"/> + <uncheckOption selector="{{AdminCategorySEOSection.UrlKeyDefaultValueCheckbox}}" stepKey="uncheckUseDefaultUrlKey"/> + <fillField selector="{{AdminCategorySEOSection.UrlKeyInput}}" userInput="{{_defaultCategory.name_lwr}}-hattest" stepKey="enterURLKey"/> + <uncheckOption selector="{{AdminCategorySEOSection.UrlKeyRedirectCheckbox}}" stepKey="uncheckRedirect1"/> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategoryAfterFirstSeoUpdate"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccessMessage"/> + <amOnPage url="" stepKey="goToStorefront"/> + <waitForPageLoad stepKey="waitForFrontendLoad"/> + <click stepKey="clickCategory" selector="{{StorefrontHeaderSection.NavigationCategoryByName(_defaultCategory.name)}}"/> + <see selector="{{StorefrontCategoryMainSection.CategoryTitle}}" userInput="{{_defaultCategory.name}}" stepKey="assertCategoryOnStorefront"/> + <seeInTitle userInput="{{_defaultCategory.name}}" stepKey="seeCategoryNameInTitle"/> + <seeInCurrentUrl stepKey="verifyUrlKey" url="{{_defaultCategory.name_lwr}}-hattest.html"/> + + <!-- Update SEO key to original, uncheck "Create Redirect", confirm in frontend, delete category --> + <!--Switch to "Default Store View" scope--> + <actionGroup ref="switchCategoryStoreView" stepKey="SwitchStoreView2"> + <argument name="Store" value="_defaultStore.name"/> + <argument name="CatName" value="_defaultCategory.name"/> + </actionGroup> + <click selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="openSeoSection2"/> + <fillField selector="{{AdminCategorySEOSection.UrlKeyInput}}" userInput="{{_defaultCategory.name_lwr}}" stepKey="enterOriginalURLKey"/> + <uncheckOption selector="{{AdminCategorySEOSection.UrlKeyRedirectCheckbox}}" stepKey="uncheckRedirect2"/> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategoryAfterOriginalSeoKey"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccessMessageAfterOriginalSeoKey"/> + <amOnPage url="" stepKey="goToStorefrontAfterOriginalSeoKey"/> + <waitForPageLoad stepKey="waitForFrontendLoadAfterOriginalSeoKey"/> + <click stepKey="clickCategoryAfterOriginalSeoKey" selector="{{StorefrontHeaderSection.NavigationCategoryByName(_defaultCategory.name)}}"/> + <see selector="{{StorefrontCategoryMainSection.CategoryTitle}}" userInput="{{_defaultCategory.name}}" stepKey="assertCategoryOnStorefront2"/> + <seeInTitle userInput="{{_defaultCategory.name}}" stepKey="seeCategoryNameInTitle2"/> + <seeInCurrentUrl stepKey="verifyUrlKeyAfterOriginalSeoKey" url="{{_defaultCategory.name_lwr}}.html"/> + </test> +</tests> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdvanceCatalogSearchSimpleProductTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdvanceCatalogSearchSimpleProductTest.xml new file mode 100644 index 0000000000000..a302fa58ec241 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdvanceCatalogSearchSimpleProductTest.xml @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdvanceCatalogSearchSimpleProductByNameTest"> + <annotations> + <features value="Catalog"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search simple product with product name"/> + <description value="Guest customer should be able to advance search simple product with product name"/> + <severity value="MAJOR"/> + <testCaseId value="MC-132"/> + <group value="Catalog"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="product"/> + </before> + <after> + <deleteData createDataKey="product" stepKey="delete"/> + </after> + </test> + <test name="AdvanceCatalogSearchSimpleProductBySkuTest"> + <annotations> + <features value="Catalog"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search simple product with product sku"/> + <description value="Guest customer should be able to advance search simple product with product sku"/> + <severity value="MAJOR"/> + <testCaseId value="MC-133"/> + <group value="Catalog"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="product"/> + </before> + <after> + <deleteData createDataKey="product" stepKey="delete"/> + </after> + </test> + <test name="AdvanceCatalogSearchSimpleProductByDescriptionTest"> + <annotations> + <features value="Catalog"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search simple product with product description"/> + <description value="Guest customer should be able to advance search simple product with product description"/> + <severity value="MAJOR"/> + <testCaseId value="MC-134"/> + <group value="Catalog"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="product"/> + </before> + <after> + <deleteData createDataKey="product" stepKey="delete"/> + </after> + </test> + <test name="AdvanceCatalogSearchSimpleProductByShortDescriptionTest"> + <annotations> + <features value="Catalog"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search simple product with product short description"/> + <description value="Guest customer should be able to advance search simple product with product short description"/> + <severity value="MAJOR"/> + <testCaseId value="MC-135"/> + <group value="Catalog"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="product"/> + </before> + <after> + <deleteData createDataKey="product" stepKey="delete"/> + </after> + </test> + <test name="AdvanceCatalogSearchSimpleProductByPriceTest"> + <annotations> + <features value="Catalog"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search simple product with product price"/> + <description value="Guest customer should be able to advance search simple product with product price"/> + <severity value="MAJOR"/> + <testCaseId value="MC-136"/> + <group value="Catalog"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="product"/> + <getData entity="GetProduct" stepKey="arg1"> + <requiredEntity createDataKey="product"/> + </getData> + <getData entity="GetProduct" stepKey="arg2"> + <requiredEntity createDataKey="product"/> + </getData> + <getData entity="GetProduct" stepKey="arg3"> + <requiredEntity createDataKey="product"/> + </getData> + </before> + <after> + <deleteData createDataKey="product" stepKey="delete"/> + </after> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml index 899dc18a6c744..84035adaa90e6 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/DeleteCategoriesTest.xml @@ -10,9 +10,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="DeleteCategoriesTest"> <annotations> - <features value="Delete categories"/> - <title value="Delete categories."/> - <description value="Delete Default Root Category and subcategories and vefify after products on storefront."/> + <features value="Catalog"/> + <title value="Admin should be able to delete the default root category and subcategories and still see products in the storefront"/> + <description value="Admin should be able to delete the default root category and subcategories and still see products in the storefront"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-46344"/> <group value="testNotIsolated"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CAdminTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CAdminTest.xml index 7ce754e8f009b..0f466ccc3d994 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CAdminTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/EndToEndB2CAdminTest.xml @@ -39,7 +39,7 @@ <argument name="product" value="SimpleProduct"/> </actionGroup> <actionGroup ref="addProductImage" stepKey="addImageForProductSimple"> - <argument name="image" value="ImageUpload"/> + <argument name="image" value="ProductImage"/> </actionGroup> <actionGroup ref="saveProductForm" stepKey="saveSimpleProduct"/> <click selector="{{AdminProductFormActionSection.backButton}}" stepKey="clickBackToGridSimple"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/SaveProductWithCustomOptionsSecondWebsiteTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/SaveProductWithCustomOptionsSecondWebsiteTest.xml index cc33059dd10b6..e938bee27eb47 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/SaveProductWithCustomOptionsSecondWebsiteTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/SaveProductWithCustomOptionsSecondWebsiteTest.xml @@ -18,32 +18,44 @@ <testCaseId value="MAGETWO-91436"/> <group value="product"/> </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--Create new website --> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createAdditionalWebsite"> + <argument name="newWebsiteName" value="Second Website"/> + <argument name="websiteCode" value="second_website"/> + </actionGroup> + <!--Create new Store Group --> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createNewStore"> + <argument name="website" value="Second Website"/> + <argument name="storeGroupName" value="Second Store"/> + <argument name="storeGroupCode" value="second_store"/> + </actionGroup> + + <!--Create Store view --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="amOnAdminSystemStorePage"/> + <click selector="{{AdminStoresMainActionsSection.createStoreViewButton}}" stepKey="createStoreViewButton"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <selectOption userInput="Second Store" selector="{{AdminNewStoreSection.storeGrpDropdown}}" stepKey="selectStoreGroup"/> + <fillField userInput="Second Store View" selector="{{AdminNewStoreSection.storeNameTextField}}" stepKey="fillStoreViewName"/> + <fillField userInput="second_store_view" selector="{{AdminNewStoreSection.storeCodeTextField}}" stepKey="fillStoreViewCode"/> + <selectOption userInput="1" selector="{{AdminNewStoreSection.statusDropdown}}" stepKey="enableStoreViewStatus"/> + <click selector="{{AdminStoresMainActionsSection.saveButton}}" stepKey="clickStoreViewSaveButton"/> + <waitForElementVisible selector="{{AdminNewStoreSection.acceptNewStoreViewCreation}}" stepKey="waitForAcceptNewStoreViewCreationModal" /> + <conditionalClick selector="{{AdminNewStoreSection.acceptNewStoreViewCreation}}" dependentSelector="{{AdminNewStoreSection.acceptNewStoreViewCreation}}" visible="true" stepKey="AcceptNewStoreViewCreation"/> + <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" stepKey="waitForPageReolad"/> + <see userInput="You saved the store view." stepKey="seeSaveMessage" /> + </before> <after> <actionGroup ref="ResetWebUrlOptions" stepKey="resetUrlOption"/> - <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteWebsite"/> - + <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteTestWebsite"> + <argument name="websiteName" value="Second Website"/> + </actionGroup> <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> </after> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="EnableWebUrlOptions" stepKey="addStoreCodeToUrls"/> - <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="addnewWebsite"/> - <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="addNewStoreGroup"/> - - <!--Create Store view --> - <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="amOnAdminSystemStorePage"/> - <click selector="{{AdminStoresMainActionsSection.createStoreViewButton}}" stepKey="createStoreViewButton"/> - <waitForPageLoad stepKey="waitForProductPageLoad"/> - <selectOption userInput="Second Store" selector="{{AdminNewStoreSection.storeGrpDropdown}}" stepKey="selectStoreGroup"/> - <fillField userInput="Second Store View" selector="{{AdminNewStoreSection.storeNameTextField}}" stepKey="fillStoreViewName"/> - <fillField userInput="second_store_view" selector="{{AdminNewStoreSection.storeCodeTextField}}" stepKey="fillStoreViewCode"/> - <selectOption userInput="1" selector="{{AdminNewStoreSection.statusDropdown}}" stepKey="enableStoreViewStatus"/> - <click selector="{{AdminStoresMainActionsSection.saveButton}}" stepKey="clickStoreViewSaveButton"/> - <waitForElementVisible selector="{{AdminNewStoreSection.acceptNewStoreViewCreation}}" stepKey="waitForAcceptNewStoreViewCreationModal" /> - <conditionalClick selector="{{AdminNewStoreSection.acceptNewStoreViewCreation}}" dependentSelector="{{AdminNewStoreSection.acceptNewStoreViewCreation}}" visible="true" stepKey="AcceptNewStoreViewCreation"/> - <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" stepKey="waitForPageReolad"/> - <see userInput="You saved the store view." stepKey="seeSaveMessage" /> + <actionGroup ref="EnableWebUrlOptions" stepKey="addStoreCodeToUrls"/> <!--Create a Simple Product with Custom Options --> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToCatalogProductGrid"/> <click selector="{{AdminProductGridActionSection.addProductToggle}}" stepKey="clickAddProductDropdown"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/SimpleProductTwoCustomOptionsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/SimpleProductTwoCustomOptionsTest.xml new file mode 100644 index 0000000000000..2710002d625d7 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/SimpleProductTwoCustomOptionsTest.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="SimpleProductTwoCustomOptionsTest"> + <annotations> + <features value="Catalog"/> + <stories value="Create simple product with two custom options" /> + <title value="Admin should be able to create simple product with two custom options"/> + <description value="Admin should be able to create simple product with two custom options"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-248"/> + <group value="Catalog"/> + </annotations> + <before> + <!-- log in as admin --> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + + <!--Create product--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + <waitForPageLoad stepKey="waitForProductIndexPage"/> + <actionGroup ref="goToCreateProductPage" stepKey="goToCreateSimpleProduct"> + <argument name="product" value="SimpleProduct3"/> + </actionGroup> + <actionGroup ref="fillMainProductFormNoWeight" stepKey="fillSimpleProductMain"> + <argument name="product" value="SimpleProduct3"/> + </actionGroup> + </before> + <after> + <!-- Delete the created product --> + <actionGroup ref="deleteProductUsingProductGrid" stepKey="deleteProduct"> + <argument name="product" value="SimpleProduct3"/> + </actionGroup> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + </after> + + <!-- opens the custom option panel and clicks add options --> + <click stepKey="openCustomizableOptions" selector="{{AdminProductCustomizableOptionsSection.customezableOptions}}"/> + <waitForPageLoad stepKey="waitForCustomOptionsOpen"/> + + <!-- Create a custom option with 2 values --> + <actionGroup ref="CreateCustomRadioOptions" stepKey="createCustomOption1"> + <argument name="customOptionName" value="ProductOptionRadiobutton.title"/> + <argument name="productOption" value="ProductOptionField"/> + <argument name="productOption2" value="ProductOptionField2"/> + </actionGroup> + + <!-- Create another custom option with 2 values --> + <actionGroup ref="CreateCustomRadioOptions" stepKey="createCustomOption2"> + <argument name="customOptionName" value="ProductOptionRadiobutton.title"/> + <argument name="productOption" value="ProductOptionField"/> + <argument name="productOption2" value="ProductOptionField2"/> + </actionGroup> + + <!-- Save the product --> + <click stepKey="saveProduct" selector="{{AdminProductFormActionSection.saveButton}}"/> + <waitForPageLoad stepKey="waitForProductSaved"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccess"/> + + <!-- navigate to the created product page --> + <amOnPage url="/{{SimpleProduct3.name}}.html" stepKey="goToCreatedProduct"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + + <!-- Check to make sure all of the created names are there --> + <see stepKey="assertNameInFirstOption" selector="{{StorefrontProductInfoMainSection.nthCustomOption('1')}}" userInput="{{ProductOptionField.title}}"/> + <see stepKey="assertNameInSecondOption" selector="{{StorefrontProductInfoMainSection.nthCustomOption('2')}}" userInput="{{ProductOptionField.title}}"/> + <see stepKey="assertSecondNameInFirstOption" selector="{{StorefrontProductInfoMainSection.nthCustomOption('1')}}" userInput="{{ProductOptionField2.title}}"/> + <see stepKey="assertSecondNameInSecondOption" selector="{{StorefrontProductInfoMainSection.nthCustomOption('2')}}" userInput="{{ProductOptionField2.title}}"/> + + <!-- Check to see that all of the created prices are there --> + <see stepKey="assertPriceInFirstOption" selector="{{StorefrontProductInfoMainSection.nthCustomOption('1')}}" userInput="{{ProductOptionField.price}}"/> + <see stepKey="assertPriceInSecondOption" selector="{{StorefrontProductInfoMainSection.nthCustomOption('2')}}" userInput="{{ProductOptionField.price}}"/> + <see stepKey="assertSecondPriceInFirstOption" selector="{{StorefrontProductInfoMainSection.nthCustomOption('1')}}" userInput="{{ProductOptionField2.price}}"/> + <see stepKey="assertSecondPriceInSecondOption" selector="{{StorefrontProductInfoMainSection.nthCustomOption('2')}}" userInput="{{ProductOptionField2.price}}"/> + + <!-- select two of the radio buttons --> + <click stepKey="selectFirstCustomOption" selector="{{StorefrontProductInfoMainSection.nthCustomOptionInput('1','2')}}"/> + <click stepKey="selectSecondCustomOption" selector="{{StorefrontProductInfoMainSection.nthCustomOptionInput('2','1')}}"/> + + <!-- Check that the price has actually changed --> + <see stepKey="assertPriceHasChanged" selector="{{StorefrontProductInfoMainSection.productPrice}}" userInput="153.00"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/StorefrontProductNameWithDoubleQuote.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/StorefrontProductNameWithDoubleQuote.xml new file mode 100644 index 0000000000000..a848515aee873 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/StorefrontProductNameWithDoubleQuote.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontProductNameWithDoubleQuote"> + <annotations> + <title value="Product with double quote in name"/> + <description value="Product with a double quote in the name should appear correctly on the storefront"/> + <severity value="CRITICAL"/> + <group value="product"/> + <testCaseId value="MAGETWO-92384"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + </before> + <after> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + </after> + + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--Create product via admin--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex"/> + <waitForPageLoad stepKey="waitForProductIndexPage"/> + <actionGroup ref="goToCreateProductPage" stepKey="goToProductCreatePage"> + <argument name="product" value="SimpleProductNameWithDoubleQuote"/> + </actionGroup> + <actionGroup ref="fillMainProductForm" stepKey="fillProductForm"> + <argument name="product" value="SimpleProductNameWithDoubleQuote"/> + </actionGroup> + <searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" parameterArray="[$$createCategory.name$$]" stepKey="selectCategory"/> + <actionGroup ref="addProductImage" stepKey="addImageToProduct"> + <argument name="image" value="ProductImage"/> + </actionGroup> + <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + + <!--Check product in category listing--> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="goToCategoryPage"/> + <seeElement selector="{{StorefrontCategoryProductSection.ProductImageByNameAndSrc(SimpleProductNameWithDoubleQuote.name, ProductImage.fileName)}}" stepKey="seeCorrectImageCategoryPage"/> + <see selector="{{StorefrontCategoryProductSection.ProductTitleByName(SimpleProductNameWithDoubleQuote.name)}}" userInput="{{SimpleProductNameWithDoubleQuote.name}}" stepKey="seeCorrectNameCategoryPage"/> + <see selector="{{StorefrontCategoryProductSection.ProductPriceByName(SimpleProductNameWithDoubleQuote.name)}}" userInput="${{SimpleProductNameWithDoubleQuote.price}}" stepKey="seeCorrectPriceCategoryPage"/> + <!--Open product display page--> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName(SimpleProductNameWithDoubleQuote.name)}}" stepKey="clickProductToGoProductPage"/> + <waitForPageLoad stepKey="waitForProductDisplayPageLoad"/> + <see selector="{{StorefrontProductInfoMainSection.productName}}" userInput="{{SimpleProductNameWithDoubleQuote.name}}" stepKey="seeCorrectName"/> + <see selector="{{StorefrontProductInfoMainSection.productSku}}" userInput="{{SimpleProductNameWithDoubleQuote.sku}}" stepKey="seeCorrectSku"/> + <see selector="{{StorefrontProductInfoMainSection.productPrice}}" userInput="${{SimpleProductNameWithDoubleQuote.price}}" stepKey="seeCorrectPrice"/> + <seeElement selector="{{StorefrontProductInfoMainSection.productImageSrc(ProductImage.fileName)}}" stepKey="seeCorrectImage"/> + <see selector="{{StorefrontProductInfoMainSection.stock}}" userInput="In Stock" stepKey="seeInStock"/> + <see selector="{{StorefrontNavigationSection.breadcrumbs}}" userInput="$$createCategory.name$$" stepKey="seeCorrectBreadCrumbCategory"/> + <see selector="{{StorefrontNavigationSection.breadcrumbs}}" userInput="{{SimpleProductNameWithDoubleQuote.name}}" stepKey="seeCorrectBreadCrumbProduct"/> + + <!--Remove product--> + <actionGroup ref="deleteProductUsingProductGrid" stepKey="deleteProduct"> + <argument name="product" value="SimpleProductNameWithDoubleQuote"/> + </actionGroup> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViews.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViews.xml index 36fd985da8cb2..93585f8c14985 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViews.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViews.xml @@ -10,9 +10,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest"> <annotations> - <features value="Purchase a product with Custom Options on different Store Views"/> - <title value="You should be able to sell products with different variants of your own."/> - <description value="You should be able to sell products with different variants of your own."/> + <features value="Catalog"/> + <title value="Admin should be able to sell products with different variants of their own"/> + <description value="Admin should be able to sell products with different variants of their own"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-58184"/> <group value="product"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/StorefrontPurchaseProductWithCustomOptions.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/StorefrontPurchaseProductWithCustomOptions.xml index 4e338c3178703..fa81e15833b81 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/StorefrontPurchaseProductWithCustomOptions.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/StorefrontPurchaseProductWithCustomOptions.xml @@ -10,10 +10,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="StorefrontPurchaseProductWithCustomOptions"> <annotations> - <features value="Purchase a product with Custom Options of different types"/> + <features value="Catalog"/> <stories value="Purchase a product with Custom Options of different types"/> - <title value="You should be able to sell products with different variants of your own."/> - <description value="You should be able to sell products with different variants of your own."/> + <title value="Admin should be able to sell products with different variants of their own"/> + <description value="Admin should be able to sell products with different variants of their own"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-61717"/> <!--Skip because of issue MAGETWO-90719--> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyChildCategoriesShouldNotIncludeInMenuTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyChildCategoriesShouldNotIncludeInMenuTest.xml index 3010da58b27aa..53c0ba041c77f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyChildCategoriesShouldNotIncludeInMenuTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyChildCategoriesShouldNotIncludeInMenuTest.xml @@ -10,9 +10,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="VerifyChildCategoriesShouldNotIncludeInMenuTest"> <annotations> - <features value="Test child categories should not include in menu"/> - <title value="Test child categories should not include in menu."/> - <description value="Test child categories should not include in menu."/> + <features value="Catalog"/> + <title value="Customer should not see categories that are not included in the menu"/> + <description value="Customer should not see categories that are not included in the menu"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-72238"/> <group value="category"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyDefaultWYSIWYGToolbarOnProductTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyDefaultWYSIWYGToolbarOnProductTest.xml index 7657306744615..b0146f1c8deef 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyDefaultWYSIWYGToolbarOnProductTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyDefaultWYSIWYGToolbarOnProductTest.xml @@ -10,11 +10,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="VerifyDefaultWYSIWYGToolbarOnProductTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Catalog"/> <stories value="MAGETWO-70412-Default toolbar configuration in Magento"/> <group value="Catalog"/> - <title value="You should be able to see default toolbar display on Description content area"/> - <description value="You should be able to see default toolbar display on Description content area"/> + <title value="Admin should be able to see default toolbar display on Description content area"/> + <description value="Admin should be able to see default toolbar display on Description content area"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-80505"/> </annotations> @@ -49,11 +49,11 @@ </test> <test name="Verifydefaultcontrolsonproductshortdescription"> <annotations> - <features value="Default WYSIWYG toolbar configuration in Magento"/> + <features value="Catalog"/> <stories value="Default toolbar configuration in Magento-MAGETWO-70412"/> <group value="WYSIWYG"/> - <title value="You should be able to see default toolbar display on Short Description content area"/> - <description value="You should be able to see default toolbar display on Short Description content area"/> + <title value="Admin should be able to see default toolbar display on Short Description content area"/> + <description value="Admin should be able to see default toolbar display on Short Description content area"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-80505"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogTest.xml index f7dbc78454a4e..f7ff2f047ea5f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogTest.xml @@ -10,11 +10,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Catalog"/> <stories value="MAGETWO-72137-Apply new WYSIWYG on Categories Page"/> <group value="Catalog"/> - <title value="Admin see TinyMCEv4.6 is native WYSIWYG on Catalog Page"/> - <description value="Admin see TinyMCEv4.6 is native WYSIWYG on Catalog Page"/> + <title value="Admin should see TinyMCEv4.6 is the native WYSIWYG on Catalog Page"/> + <description value="Admin should see TinyMCEv4.6 is the native WYSIWYG on Catalog Page"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-82551"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnProductTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnProductTest.xml index 7492d78cccff7..7e78b476ae7dc 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnProductTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnProductTest.xml @@ -9,11 +9,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="VerifyTinyMCEv4IsNativeWYSIWYGOnProductTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Catalog"/> <stories value="MAGETWO-72114-TinyMCE v4.6 as a native WYSIWYG editor"/> <group value="Catalog"/> - <title value="Admin see TinyMCEv4.6 is native WYSIWYG on Product Page"/> - <description value="Admin should be able to switch between 2 version of Tinymce in the admin back-end."/> + <title value="Admin should see TinyMCEv4.6 is the native WYSIWYG on Product Page"/> + <description value="Admin should see TinyMCEv4.6 is the native WYSIWYG on Product Page"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-81819"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/Test/AdvanceCatalogSearchSimpleProductTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/Test/AdvanceCatalogSearchSimpleProductTest.xml new file mode 100644 index 0000000000000..11bc308902ca0 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/Test/AdvanceCatalogSearchSimpleProductTest.xml @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdvanceCatalogSearchSimpleProductByNameTest"> + <annotations> + <features value="CatalogSearch"/> + <group value="CatalogSearch"/> + </annotations> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameActionGroup" stepKey="search"> + <argument name="name" value="$$product.name$$"/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> + <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> + </test> + <test name="AdvanceCatalogSearchSimpleProductBySkuTest"> + <annotations> + <features value="CatalogSearch"/> + <group value="CatalogSearch"/> + </annotations> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductSkuActionGroup" stepKey="search"> + <argument name="sku" value="$$product.sku$$"/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> + <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> + </test> + <test name="AdvanceCatalogSearchSimpleProductByDescriptionTest"> + <annotations> + <features value="CatalogSearch"/> + <group value="CatalogSearch"/> + </annotations> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByDescriptionActionGroup" stepKey="search"> + <argument name="description" value="$$product.custom_attributes[description]$$"/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> + <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> + </test> + <test name="AdvanceCatalogSearchSimpleProductByShortDescriptionTest"> + <annotations> + <features value="CatalogSearch"/> + <group value="CatalogSearch"/> + </annotations> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByShortDescriptionActionGroup" stepKey="search"> + <argument name="shortDescription" value="$$product.custom_attributes[short_description]$$"/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> + <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> + </test> + <test name="AdvanceCatalogSearchSimpleProductByPriceTest"> + <annotations> + <features value="CatalogSearch"/> + <group value="CatalogSearch"/> + </annotations> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndPriceActionGroup" stepKey="search"> + <argument name="name" value="$$arg1.name$$"/> + <argument name="priceFrom" value="$$arg2.price$$"/> + <argument name="priceTo" value="$$arg3.price$$"/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> + <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$arg1.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/Test/AdvanceCatalogSearchSimpleProductsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/Test/AdvanceCatalogSearchSimpleProductsTest.xml deleted file mode 100644 index f52a86810842e..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/Test/AdvanceCatalogSearchSimpleProductsTest.xml +++ /dev/null @@ -1,140 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="AdvanceCatalogSearchSimpleProductByNameTest"> - <annotations> - <features value="CatalogSearch"/> - <stories value="Advanced Catalog Product Search for all product types"/> - <title value="Guest customer should be able to advance search simple product with product name"/> - <description value="Guest customer should be able to advance search simple product with product name"/> - <severity value="MAJOR"/> - <testCaseId value="MC-132"/> - <group value="CatalogSearch"/> - </annotations> - <before> - <createData entity="ApiProductWithDescription" stepKey="createProductOne"/> - </before> - <after> - <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> - </after> - - <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> - <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameActionGroup" stepKey="search"> - <argument name="name" value="$$createProductOne.name$$"/> - </actionGroup> - <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> - </test> - <test name="AdvanceCatalogSearchSimpleProductBySkuTest"> - <annotations> - <features value="CatalogSearch"/> - <stories value="Advanced Catalog Product Search for all product types"/> - <title value="Guest customer should be able to advance search simple product with product sku"/> - <description value="Guest customer should be able to advance search simple product with product sku"/> - <severity value="MAJOR"/> - <testCaseId value="MC-133"/> - <group value="CatalogSearch"/> - </annotations> - <before> - <createData entity="ApiProductWithDescription" stepKey="createProductOne"/> - </before> - <after> - <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> - </after> - - <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> - <actionGroup ref="StorefrontAdvancedCatalogSearchByProductSkuActionGroup" stepKey="search"> - <argument name="sku" value="$$createProductOne.sku$$"/> - </actionGroup> - <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> - <see userInput="$$createProductOne.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> - </test> - - <test name="AdvanceCatalogSearchSimpleProductByDescriptionTest"> - <annotations> - <features value="CatalogSearch"/> - <stories value="Advanced Catalog Product Search for all product types"/> - <title value="Guest customer should be able to advance search simple product with product description"/> - <description value="Guest customer should be able to advance search simple product with product description"/> - <severity value="MAJOR"/> - <testCaseId value="MC-134"/> - <group value="CatalogSearch"/> - </annotations> - <before> - <createData entity="ApiProductWithDescription" stepKey="createProductOne"/> - </before> - <after> - <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> - </after> - - <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> - <actionGroup ref="StorefrontAdvancedCatalogSearchByDescriptionActionGroup" stepKey="search"> - <argument name="description" value="$$createProductOne.custom_attributes[description]$$"/> - </actionGroup> - <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> - <see userInput="$$createProductOne.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> - </test> - - <test name="AdvanceCatalogSearchSimpleProductByShortDescriptionTest"> - <annotations> - <features value="CatalogSearch"/> - <stories value="Advanced Catalog Product Search for all product types"/> - <title value="Guest customer should be able to advance search simple product with product short description"/> - <description value="Guest customer should be able to advance search simple product with product short description"/> - <severity value="MAJOR"/> - <testCaseId value="MC-135"/> - <group value="CatalogSearch"/> - </annotations> - <before> - <createData entity="ApiProductWithDescription" stepKey="createProductOne"/> - </before> - <after> - <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> - </after> - - <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> - <actionGroup ref="StorefrontAdvancedCatalogSearchByShortDescriptionActionGroup" stepKey="search"> - <argument name="shortDescription" value="$$createProductOne.custom_attributes[short_description]$$"/> - </actionGroup> - <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> - <see userInput="$$createProductOne.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> - </test> - - <test name="AdvanceCatalogSearchSimpleProductByPriceTest"> - <annotations> - <features value="CatalogSearch"/> - <stories value="Advanced Catalog Product Search for all product types"/> - <title value="Guest customer should be able to advance search simple product with product price"/> - <description value="Guest customer should be able to advance search simple product with product price"/> - <severity value="MAJOR"/> - <testCaseId value="MC-136"/> - <group value="CatalogSearch"/> - </annotations> - <before> - <createData entity="ApiProductWithDescription" stepKey="createProductOne"/> - </before> - <after> - <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> - </after> - - <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> - <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndPriceActionGroup" stepKey="search"> - <argument name="name" value="$$createProductOne.name$$"/> - <argument name="priceFrom" value="$$createProductOne.price$$"/> - <argument name="priceTo" value="$$createProductOne.price$$"/> - </actionGroup> - <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> - <see userInput="$$createProductOne.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/Test/AdvanceCatalogSearchVirtualProductsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/Test/AdvanceCatalogSearchVirtualProductsTest.xml deleted file mode 100644 index 80b1b294fecd5..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogSearch/Test/AdvanceCatalogSearchVirtualProductsTest.xml +++ /dev/null @@ -1,141 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="AdvanceCatalogSearchVirtualProductByNameTest"> - <annotations> - <features value="CatalogSearch"/> - <stories value="Advanced Catalog Product Search for all product types"/> - <title value="Guest customer should be able to advance search virtual product with product name"/> - <description value="Guest customer should be able to advance search virtual product with product name"/> - <severity value="MAJOR"/> - <testCaseId value="MC-137"/> - <group value="CatalogSearch"/> - </annotations> - <before> - <createData entity="ApiVirtualProductWithDescription" stepKey="createProductOne"/> - </before> - <after> - <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> - </after> - - <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> - <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameActionGroup" stepKey="search"> - <argument name="name" value="$$createProductOne.name$$"/> - </actionGroup> - <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> - <see userInput="$$createProductOne.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> - </test> - <test name="AdvanceCatalogSearchVirtualProductBySkuTest"> - <annotations> - <features value="CatalogSearch"/> - <stories value="Advanced Catalog Product Search for all product types"/> - <title value="Guest customer should be able to advance search virtual product with product sku"/> - <description value="Guest customer should be able to advance search virtual product with product sku"/> - <severity value="MAJOR"/> - <testCaseId value="MC-162"/> - <group value="CatalogSearch"/> - </annotations> - <before> - <createData entity="ApiVirtualProductWithDescription" stepKey="createProductOne"/> - </before> - <after> - <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> - </after> - - <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> - <actionGroup ref="StorefrontAdvancedCatalogSearchByProductSkuActionGroup" stepKey="search"> - <argument name="sku" value="$$createProductOne.sku$$"/> - </actionGroup> - <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> - <see userInput="$$createProductOne.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> - </test> - - <test name="AdvanceCatalogSearchVirtualProductByDescriptionTest"> - <annotations> - <features value="CatalogSearch"/> - <stories value="Advanced Catalog Product Search for all product types"/> - <title value="Guest customer should be able to advance search virtual product with product description"/> - <description value="Guest customer should be able to advance search virtual product with product description"/> - <severity value="MAJOR"/> - <testCaseId value="MC-163"/> - <group value="CatalogSearch"/> - </annotations> - <before> - <createData entity="ApiVirtualProductWithDescription" stepKey="createProductOne"/> - </before> - <after> - <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> - </after> - - <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> - <actionGroup ref="StorefrontAdvancedCatalogSearchByDescriptionActionGroup" stepKey="search"> - <argument name="description" value="$$createProductOne.custom_attributes[description]$$"/> - </actionGroup> - <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> - <see userInput="$$createProductOne.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> - </test> - - <test name="AdvanceCatalogSearchVirtualProductByShortDescriptionTest"> - <annotations> - <features value="CatalogSearch"/> - <stories value="Advanced Catalog Product Search for all product types"/> - <title value="Guest customer should be able to advance search virtual product with product short description"/> - <description value="Guest customer should be able to advance search virtual product with product short description"/> - <severity value="MAJOR"/> - <testCaseId value="MC-164"/> - <group value="CatalogSearch"/> - </annotations> - <before> - <createData entity="ApiVirtualProductWithDescription" stepKey="createProductOne"/> - </before> - <after> - <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> - </after> - - <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> - <actionGroup ref="StorefrontAdvancedCatalogSearchByShortDescriptionActionGroup" stepKey="search"> - <argument name="shortDescription" value="$$createProductOne.custom_attributes[short_description]$$"/> - </actionGroup> - <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> - <see userInput="$$createProductOne.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> - </test> - - <test name="AdvanceCatalogSearchVirtualProductByPriceTest"> - <annotations> - <features value="CatalogSearch"/> - <stories value="Advanced Catalog Product Search for all product types"/> - <title value="Guest customer should be able to advance search virtual product with product price"/> - <description value="Guest customer should be able to advance search virtual product with product price"/> - <severity value="MAJOR"/> - <testCaseId value="MC-165"/> - <group value="CatalogSearch"/> - </annotations> - <before> - <createData entity="ApiVirtualProductWithDescription" stepKey="createProductOne"/> - </before> - <after> - <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> - </after> - - <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroup"/> - <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndPriceActionGroup" stepKey="search"> - <argument name="name" value="$$createProductOne.name$$"/> - <argument name="priceFrom" value="$$createProductOne.price$$"/> - <argument name="priceTo" value="$$createProductOne.price$$"/> - </actionGroup> - <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> - <see userInput="$$createProductOne.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> - </test> -</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml index e24b59e1cf115..98b3e439382b7 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml @@ -25,4 +25,24 @@ <fillField selector="{{CheckoutPaymentSection.guestTelephone}}" userInput="{{customerAddressVar.telephone}}" stepKey="enterTelephone"/> </actionGroup> + <actionGroup name="LoggedInCheckoutFillNewBillingAddressActionGroup"> + <arguments> + <argument name="Address"/> + <!-- the classPrefix argument is to specifically select the inputs of the correct form + this is to prevent having 3 action groups doing essentially the same thing --> + <argument name="classPrefix" type="string" defaultValue=""/> + </arguments> + <fillField stepKey="fillFirstName" selector="{{classPrefix}} {{CheckoutShippingSection.firstName}}" userInput="{{Address.firstname}}"/> + <fillField stepKey="fillLastName" selector="{{classPrefix}} {{CheckoutShippingSection.lastName}}" userInput="{{Address.lastname}}"/> + <fillField stepKey="fillCompany" selector="{{classPrefix}} {{CheckoutShippingSection.company}}" userInput="{{Address.company}}"/> + <fillField stepKey="fillPhoneNumber" selector="{{classPrefix}} {{CheckoutShippingSection.telephone}}" userInput="{{Address.telephone}}"/> + <fillField stepKey="fillStreetAddress1" selector="{{classPrefix}} {{CheckoutShippingSection.street}}" userInput="{{Address.street[0]}}"/> + <fillField stepKey="fillStreetAddress2" selector="{{classPrefix}} {{CheckoutShippingSection.street2}}" userInput="{{Address.street[1]}}"/> + <fillField stepKey="fillCityName" selector="{{classPrefix}} {{CheckoutShippingSection.city}}" userInput="{{Address.city}}"/> + <selectOption stepKey="selectState" selector="{{classPrefix}} {{CheckoutShippingSection.region}}" userInput="{{Address.state}}"/> + <fillField stepKey="fillZip" selector="{{classPrefix}} {{CheckoutShippingSection.postcode}}" userInput="{{Address.postcode}}"/> + <selectOption stepKey="selectCounty" selector="{{classPrefix}} {{CheckoutShippingSection.country}}" userInput="{{Address.country_id}}"/> + <waitForPageLoad stepKey="waitForFormUpdate2"/> + </actionGroup> + </actionGroups> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/ActionGroup/StorefrontProductCartActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/ActionGroup/StorefrontProductCartActionGroup.xml index d7ecdc31586b4..b98e1046c4a5b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/ActionGroup/StorefrontProductCartActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/ActionGroup/StorefrontProductCartActionGroup.xml @@ -77,4 +77,15 @@ <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickShowMinicart" /> <click selector="{{StorefrontMinicartSection.viewAndEditCart}}" stepKey="clickCart" /> </actionGroup> + + <actionGroup name="changeSummaryQuoteAddress"> + <arguments> + <argument name="taxCode"/> + </arguments> + <conditionalClick stepKey="openShippingDetails" selector="{{CheckoutCartSummarySection.shippingHeading}}" dependentSelector="{{CheckoutCartSummarySection.country}}" visible="false"/> + <selectOption stepKey="selectCountry" selector="{{CheckoutCartSummarySection.country}}" userInput="{{taxCode.country}}"/> + <selectOption stepKey="selectStateProvince" selector="{{CheckoutCartSummarySection.country}}" userInput="{{taxCode.country}}"/> + <fillField stepKey="fillZip" selector="{{CheckoutCartSummarySection.postcode}}" userInput="{{taxCode.zip}}"/> + <waitForPageLoad stepKey="waitForFormUpdate"/> + </actionGroup> </actionGroups> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Page/GuestCheckoutReviewAndPaymentsPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Page/GuestCheckoutReviewAndPaymentsPage.xml new file mode 100644 index 0000000000000..3fb6e99ed6730 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Page/GuestCheckoutReviewAndPaymentsPage.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="GuestCheckoutReviewAndPaymentsPage" url="/checkout/#payment" area="storefront" module="Magento_Checkout"> + <section name="CheckoutPaymentSection"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutCartProductSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutCartProductSection.xml index 92c10ca83a76d..fa0776c1f60c9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutCartProductSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutCartProductSection.xml @@ -26,5 +26,8 @@ parameterized="true"/> <element name="RemoveItem" type="button" selector="//table[@id='shopping-cart-table']//tbody//tr[contains(@class,'item-actions')]//a[contains(@class,'action-delete')]"/> + <element name="nthItemOption" type="block" selector=".item:nth-of-type({{numElement}}) .item-options" parameterized="true"/> + <element name="nthEditButton" type="block" selector=".item:nth-of-type({{numElement}}) .action-edit" parameterized="true"/> + <element name="nthBundleOptionName" type="text" selector=".product-item-details .item-options:nth-of-type({{numOption}}) dt" parameterized="true"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutCartSummarySection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutCartSummarySection.xml index 32a57a14cd9da..248070940542c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutCartSummarySection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutCartSummarySection.xml @@ -15,5 +15,9 @@ <element name="total" type="text" selector="//*[@id='cart-totals']//tr[@class='grand totals']//td//span[@class='price']"/> <element name="proceedToCheckout" type="button" selector=".action.primary.checkout span" timeout="30"/> <element name="discountAmount" type="text" selector="td[data-th='Discount']"/> + <element name="shippingHeading" type="button" selector="#block-shipping-heading"/> + <element name="postcode" type="input" selector="input[name='postcode']"/> + <element name="stateProvince" type="select" selector="select[name='region_id']"/> + <element name="country" type="select" selector="select[name='country_id']"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutPaymentSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutPaymentSection.xml index 2af5986cc092f..3d1e9f24b8d9a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutPaymentSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutPaymentSection.xml @@ -41,5 +41,10 @@ <element name="paymentMethodTitle" type="text" selector=".payment-method-title span" /> <element name="productOptionsByProductItemPrice" type="text" selector="//div[@class='product-item-inner']//div[@class='subtotal']//span[@class='price'][contains(.,'{{var1}}')]//ancestor::div[@class='product-item-details']//div[@class='product options']" parameterized="true"/> <element name="productOptionsActiveByProductItemPrice" type="text" selector="//div[@class='subtotal']//span[@class='price'][contains(.,'{{var1}}')]//ancestor::div[@class='product-item-details']//div[@class='product options active']" parameterized="true"/> + + <element name="tax" type="text" selector="[data-th='Tax'] span" timeout="30"/> + <element name="taxPercentage" type="text" selector=".totals-tax-details .mark"/> + <element name="orderSummaryTotalIncluding" type="text" selector="//tr[@class='grand totals incl']//span[@class='price']" /> + <element name="orderSummaryTotalExcluding" type="text" selector="//tr[@class='grand totals excl']//span[@class='price']" /> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutShippingGuestInfoSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutShippingGuestInfoSection.xml index f20ae4dac07d5..f2cca89be6c18 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutShippingGuestInfoSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutShippingGuestInfoSection.xml @@ -17,5 +17,7 @@ <element name="region" type="select" selector="select[name=region_id]"/> <element name="postcode" type="input" selector="input[name=postcode]"/> <element name="telephone" type="input" selector="input[name=telephone]"/> + <element name="next" type="button" selector="button.button.action.continue.primary" timeout="30"/> + <element name="firstShippingMethod" type="radio" selector=".row:nth-of-type(1) .col-method .radio"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutShippingSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutShippingSection.xml index 54fa168a1a4eb..247c9664caf0a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutShippingSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Checkout/Section/CheckoutShippingSection.xml @@ -10,17 +10,26 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="CheckoutShippingSection"> <element name="isShippingStep" type="text" selector="//*[@class='opc-progress-bar']/li[contains(@class, '_active') and span[contains(.,'Shipping')]]"/> + <element name="shippingTab" type="text" selector="//li[contains(@class,'opc-progress-bar-item')]//*[text()='Shipping']" timeout="30"/> <element name="selectedShippingAddress" type="text" selector=".shipping-address-item.selected-item"/> - <element name="newAddressButton" type="button" selector="#checkout-step-shipping button"/> + <element name="editAddressButton" type="button" selector=".action-edit-address" timeout="30"/> + <element name="addressDropdown" type="select" selector="[name=billing_address_id]"/> + <element name="newAddressButton" type="button" selector=".action-show-popup" timeout="30"/> <element name="email" type="input" selector="#customer-email"/> <element name="firstName" type="input" selector="input[name=firstname]"/> <element name="lastName" type="input" selector="input[name=lastname]"/> + <element name="company" type="input" selector="input[name=company]"/> <element name="street" type="input" selector="input[name='street[0]']"/> + <element name="street2" type="input" selector="input[name='street[1]']"/> <element name="city" type="input" selector="input[name=city]"/> <element name="region" type="select" selector="select[name=region_id]"/> <element name="postcode" type="input" selector="input[name=postcode]"/> + <element name="country" type="select" selector="select[name=country_id]"/> <element name="telephone" type="input" selector="input[name=telephone]"/> - <element name="next" type="button" selector="button.button.action.continue.primary"/> + <element name="saveAddress" type="button" selector=".action-save-address"/> + <element name="updateAddress" type="button" selector=".action-update"/> + <element name="next" type="button" selector="button.button.action.continue.primary" timeout="30"/> <element name="firstShippingMethod" type="radio" selector="//*[@id='checkout-shipping-method-load']//input[@class='radio']"/> + <element name="defaultShipping" type="button" selector=".billing-address-details"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/DeleteImageFromStorageActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/DeleteImageFromStorageActionGroup.xml index c4af2bc850635..c4853d9f824c0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/DeleteImageFromStorageActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/DeleteImageFromStorageActionGroup.xml @@ -9,14 +9,22 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> <actionGroup name="DeleteImageFromStorageActionGroup"> <arguments> - <argument name="Image" defaultValue="" /> + <argument name="Image"/> </arguments> - <click selector="//small[contains(text(),'{{Image.value}}')]" stepKey="selectImage" /> - <see selector="{{MediaGallerySection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn"/> - <click selector="{{MediaGallerySection.DeleteSelectedBtn}}" stepKey="clickDeleteSelected" /> - <waitForText userInput="OK" stepKey="waitForConfirm" /> - <click selector="{{MediaGallerySection.confirmDelete}}" stepKey="confirmDelete" /> - <waitForElementNotVisible selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="waitForImageDeleted" /> - <dontSeeElement selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="dontSeeImage" /> + <waitForElementVisible selector="{{MediaGallerySection.imageOrImageCopy(Image.fileName, Image.extension)}}" stepKey="waitForInitialImages"/> + <grabMultiple selector="{{MediaGallerySection.imageOrImageCopy(Image.fileName, Image.extension)}}" stepKey="initialImages"/> + <click selector="{{MediaGallerySection.imageOrImageCopy(Image.fileName, Image.extension)}}" stepKey="selectImage"/> + <waitForElementVisible selector="{{MediaGallerySection.DeleteSelectedBtn}}" stepKey="waitForDeleteBtn"/> + <click selector="{{MediaGallerySection.DeleteSelectedBtn}}" stepKey="clickDeleteSelected"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <waitForElementVisible selector="{{MediaGallerySection.confirmDelete}}" stepKey="waitForConfirmBtn"/> + <click selector="{{MediaGallerySection.confirmDelete}}" stepKey="clickConfirmBtn"/> + <waitForPageLoad stepKey="waitForPageLoad2"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear"/> + <grabMultiple selector="{{MediaGallerySection.imageOrImageCopy(Image.fileName, Image.extension)}}" stepKey="newImages"/> + <assertLessThan stepKey="assertLessImages"> + <expectedResult type="variable">initialImages</expectedResult> + <actualResult type="variable">newImages</actualResult> + </assertLessThan> </actionGroup> </actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/NavigateToMediaFolderActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/NavigateToMediaFolderActionGroup.xml index c886ab306cf92..4d5373eea3fb8 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/NavigateToMediaFolderActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/NavigateToMediaFolderActionGroup.xml @@ -9,11 +9,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> <actionGroup name="NavigateToMediaFolderActionGroup"> <arguments> - <argument name="FolderName" type="string" defaultValue="" /> + <argument name="FolderName" type="string"/> </arguments> <conditionalClick selector="{{MediaGallerySection.StorageRootArrow}}" dependentSelector="{{MediaGallerySection.checkIfArrowExpand}}" stepKey="clickArrowIfClosed" visible="true"/> - <waitForText userInput="{{FolderName}}" stepKey="waitForNewFolder" /> - <click userInput="{{FolderName}}" stepKey="clickOnCreatedFolder" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoading5" /> + <waitForText userInput="{{FolderName}}" stepKey="waitForNewFolder"/> + <click userInput="{{FolderName}}" stepKey="clickOnCreatedFolder"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoading"/> </actionGroup> </actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/SelectImageFromMediaStorageActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/SelectImageFromMediaStorageActionGroup.xml index 151ec7672d6c6..8f9b7595665f3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/SelectImageFromMediaStorageActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/SelectImageFromMediaStorageActionGroup.xml @@ -37,12 +37,12 @@ </actionGroup> <actionGroup name="attachImage"> <arguments> - <argument name="Image" defaultValue=""/> + <argument name="Image"/> </arguments> - <attachFile selector="{{MediaGallerySection.BrowseUploadImage}}" userInput="{{Image.value}}" stepKey="uploadImage1"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoading6" /> - <waitForElementVisible selector="{{MediaGallerySection.image(Image.value)}}" stepKey="waitForUploadImage1" /> - <seeElement selector="{{MediaGallerySection.imageSelected(Image.value)}}" stepKey="seeImageSelected" /> + <attachFile selector="{{MediaGallerySection.BrowseUploadImage}}" userInput="{{Image.value}}" stepKey="uploadImage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear"/> + <waitForElementVisible selector="{{MediaGallerySection.imageOrImageCopy(Image.fileName, Image.extension)}}" stepKey="waitForUploadImage"/> </actionGroup> <actionGroup name="deleteImage"> <see selector="{{MediaGallerySection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn"/> @@ -53,8 +53,9 @@ <dontSeeElement selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="dontSeeImage" /> </actionGroup> <actionGroup name="saveImage"> - <click selector="{{MediaGallerySection.InsertFile}}" stepKey="clickInsertBtn" /> - <waitForPageLoad stepKey="waitForPageLoad2"/> + <click selector="{{MediaGallerySection.InsertFile}}" stepKey="clickInsertBtn"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear"/> </actionGroup> <actionGroup name="fillOutUploadImagePopup"> <waitForElementVisible selector="{{MediaGallerySection.OkBtn}}" stepKey="waitForOkBtn" /> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Data/CmsPageData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Data/CmsPageData.xml index 857ac2a2f1b1f..25e55ea756afb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Data/CmsPageData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Data/CmsPageData.xml @@ -37,6 +37,7 @@ <data key="price">1.00</data> <data key="file_type">Upload File</data> <data key="shareable">Yes</data> + <data key="file">magento.jpg</data> <data key="value">magento.jpg</data> <data key="fileName">magento</data> <data key="extension">jpg</data> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/TinyMCESection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/TinyMCESection.xml index a158d1ed8580b..f840840587738 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/TinyMCESection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/TinyMCESection.xml @@ -36,6 +36,7 @@ <element name="Browse" type="button" selector=".mce-i-browse"/> <element name="BrowseUploadImage" type="file" selector=".fileupload" /> <element name="image" type="text" selector="//small[text()='{{var1}}']" parameterized="true"/> + <element name="imageOrImageCopy" type="text" selector="//img[contains(@alt, '{{arg1}}.{{arg2}}')]|//img[contains(@alt,'{{arg1}}_') and contains(@alt,'.{{arg2}}')]" parameterized="true"/> <element name="imageSelected" type="text" selector="//small[text()='{{var1}}']/parent::*[@class='filecnt selected']" parameterized="true"/> <element name="ImageSource" type="input" selector=".mce-combobox.mce-abs-layout-item.mce-last.mce-has-open" /> <element name="ImageDescription" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-last" /> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGBlockTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGBlockTest.xml index 5625dceeea051..d08e67999a62e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGBlockTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGBlockTest.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddImageToWYSIWYGBlockTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42041-Default WYSIWYG toolbar configuration with Magento Media Gallery"/> <group value="Cms"/> <title value="Admin should be able to add image to WYSIWYG content of Block"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGCMSTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGCMSTest.xml index c2ce1b1a53412..06265ecba60d4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGCMSTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGCMSTest.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddImageToWYSIWYGCMSTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42041-Default WYSIWYG toolbar configuration with Magento Media Gallery"/> <group value="Cms"/> <title value="Admin should be able to add image to WYSIWYG content of CMS Page"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGBlockTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGBlockTest.xml index 4de72b6f2462a..a57e0a1daafb7 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGBlockTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGBlockTest.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddVariableToWYSIWYGBlockTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42158-Variable with WYSIWYG"/> <group value="Cms"/> <title value="Admin should be able to add variable to WYSIWYG content of Block"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGCMSTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGCMSTest.xml index 5bd82bfe43780..501eaae76c7ac 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGCMSTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGCMSTest.xml @@ -9,10 +9,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddVariableToWYSIWYGCMSTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42158-Variable with WYSIWYG "/> - <title value="Insert default Magento variable into content of WYSIWYG on CMS Pages"/> - <description value="Insert default Magento variable into content of WYSIWYG on CMS Pages"/> + <title value="Admin should be able to insert the default Magento variable into content of WYSIWYG on CMS Pages"/> + <description value="Admin should be able to insert the default Magento variable into content of WYSIWYG on CMS Pages"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-83504"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGBlockTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGBlockTest.xml index 818395b8376be..19b7dac734af2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGBlockTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGBlockTest.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddWidgetToWYSIWYGBlockTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42156-Apply new WYSIWYG in Block"/> <group value="Cms"/> <title value="Admin should be able to add widget to WYSIWYG content of Block"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSPageLinkTypeTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSPageLinkTypeTest.xml index ab1d60fb6a894..94a13c282d89a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSPageLinkTypeTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSPageLinkTypeTest.xml @@ -10,11 +10,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddWidgetToWYSIWYGWithCMSPageLinkTypeTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> <group value="Cms"/> - <title value="Create CMS Page With Widget Type:CMS page link"/> - <description value="Create CMS Page With Widget Type:CMS page link"/> + <title value="Admin should be able to create a CMS page with widget type: CMS page link"/> + <description value="Admin should be able to create a CMS page with widget type: CMS page link"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-83781"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSStaticBlockTypeTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSStaticBlockTypeTest.xml index a984c360c6314..442fac5fd73f4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSStaticBlockTypeTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSStaticBlockTypeTest.xml @@ -10,11 +10,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddWidgetToWYSIWYGWithCMSStaticBlockTypeTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> <group value="Cms"/> - <title value="Create CMS Page With Widget Type:CMS Static Block"/> - <description value="Create CMS Page With Widget Type:CMS Static Block"/> + <title value="Admin should be able to create a CMS page with widget type: CMS Static Block"/> + <description value="Admin should be able to create a CMS page with widget type: CMS Static Block"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-83787"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogCategoryLinkTypeTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogCategoryLinkTypeTest.xml index 7e56daecb5669..d86bcf36d1b93 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogCategoryLinkTypeTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogCategoryLinkTypeTest.xml @@ -9,11 +9,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddWidgetToWYSIWYGWithCatalogCategoryLinkTypeTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> <group value="Cms"/> - <title value="Create CMS Page With Widget Type: Catalog category link"/> - <description value="Create CMS Page With Widget Type: Catalog category link"/> + <title value="Admin should be able to create a CMS page with widget type: Catalog category link"/> + <description value="Admin should be able to create a CMS page with widget type: Catalog category link"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-83611"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductLinkTypeTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductLinkTypeTest.xml index d736350e186b4..7f07bdfde24a3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductLinkTypeTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductLinkTypeTest.xml @@ -10,11 +10,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddWidgetToWYSIWYGWithCatalogProductLinkTypeTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> <group value="Cms"/> - <title value="Create CMS Page With Widget Type: Catalog product link"/> - <description value="Create CMS Page With Widget Type: Catalog product link"/> + <title value="Admin should be able to create a CMS page with widget type: Catalog product link"/> + <description value="Admin should be able to create a CMS page with widget type: Catalog product link"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-83788"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml index af1262a0113d0..2e225bfd55de6 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml @@ -9,11 +9,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> <group value="Cms"/> - <title value="Create CMS Page With Widget Type: Catalog product list"/> - <description value="Create CMS Page With Widget Type: Catalog product list"/> + <title value="Admin should be able to create a CMS page with widget type: Catalog product list"/> + <description value="Admin should be able to create a CMS page with widget type: Catalog product list"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-67091"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyComparedProductsTypeTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyComparedProductsTypeTest.xml index 40311c809b2ce..3313ad3e639fb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyComparedProductsTypeTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyComparedProductsTypeTest.xml @@ -10,11 +10,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddWidgetToWYSIWYGWithRecentlyComparedProductsTypeTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> <group value="Cms"/> - <title value="Create CMS Page With Widget Type: Recently Compared Products"/> - <description value="Create CMS Page With Widget Type: Recently Compared Products"/> + <title value="Admin should be able to create a CMS page with widget type: Recently Compared Products"/> + <description value="Admin should be able to create a CMS page with widget type: Recently Compared Products"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-83792"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyViewedProductsTypeTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyViewedProductsTypeTest.xml index 5ae0ddcfb4efe..177f5c6d77bc2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyViewedProductsTypeTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyViewedProductsTypeTest.xml @@ -10,11 +10,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddWidgetToWYSIWYGWithRecentlyViewedProductsTypeTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> <group value="Cms"/> - <title value="Create CMS Page With Widget Type: Recently Viewed Products"/> - <description value="Create CMS Page With Widget Type: Recently Viewed Products"/> + <title value="Admin should be able to create a CMS page with widget type: Recently Viewed Products"/> + <description value="Admin should be able to create a CMS page with widget type: Recently Viewed Products"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-83789"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsBlockTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsBlockTest.xml index 77965cfedfd4d..a5013384c4142 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsBlockTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsBlockTest.xml @@ -10,10 +10,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateDuplicatedCmsBlockTest"> <annotations> - <features value="[CMS] Drag Drop, Preview and Access to the Options of the Content Blocks MAGETWO-83848"/> + <features value="Cms"/> <stories value="CMS Block Duplication and Reset Removal MAGETWO-88797"/> - <title value="Create a duplicated CMS Block"/> - <description value="You should be able to duplicate a CMS Block via the Admin."/> + <title value="Admin should be able to duplicate a CMS block"/> + <description value="Admin should be able to duplicate a CMS block"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-89185"/> <group value="Cms"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml index 3bdd57ef2b9c8..717605d74788f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml @@ -10,10 +10,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateCmsPageTest"> <annotations> - <features value="CMS Page Creation"/> + <features value="Cms"/> <stories value="Create a CMS Page via the Admin"/> - <title value="Create a CMS Page"/> - <description value="You should be able to create a CMS Page via the Admin."/> + <title value="Admin should be able to create a CMS Page"/> + <description value="Admin should be able to create a CMS Page"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-25580"/> <group value="Cms"/> @@ -47,10 +47,10 @@ </test> <test name="AdminConfigDefaultCMSPageLayoutFromConfigurationSettingTest"> <annotations> - <features value="[CMS] WYSIWYG update MAGETWO-36659"/> + <features value="Cms"/> <stories value="Default layout configuration MAGETWO-88793"/> - <title value="Admin are able to config default layout for CMS Page from System Configuration"/> - <description value="Admin are able to select layout that will be applied by default to CMS Page, so that he does not need to change it manually every time he create a page"/> + <title value="Admin should be able to configure the default layout for CMS Page from System Configuration"/> + <description value="Admin should be able to configure the default layout for CMS Page from System Configuration"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-89025"/> <group value="Cms"/> @@ -80,10 +80,10 @@ </test> <test name="AdminCreateDuplicatedCmsPageTest"> <annotations> - <features value="[CMS] Drag Drop, Preview and Access to the Options of the Content Blocks MAGETWO-83848"/> + <features value="Cms"/> <stories value="CMS Page Duplication and Reset Removal MAGETWO-87096"/> - <title value="Create duplicated CMS Page"/> - <description value="You should be able to duplicate a CMS Page via the Admin."/> + <title value="Admin should be able to duplicate a CMS Page"/> + <description value="Admin should be able to duplicate a CMS Page"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-89184"/> <group value="Cms"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnBlockTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnBlockTest.xml index 8bd39c5d1e7aa..f45329f64926e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnBlockTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnBlockTest.xml @@ -10,11 +10,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="VerifyTinyMCEv4IsNativeWYSIWYGOnBlockTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42046-Apply new WYSIWYG on CMS Page and Block"/> <group value="Cms"/> - <title value="Admin see TinyMCEv4.6 is native WYSIWYG on Block"/> - <description value="Admin see TinyMCEv4.6 is native WYSIWYG on Block"/> + <title value="Admin should see TinyMCEv4.6 is the native WYSIWYG on Block"/> + <description value="Admin should see TinyMCEv4.6 is the native WYSIWYG on Block"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84184"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCMSPageTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCMSPageTest.xml index 718728e737a5a..6e02ab67e61d5 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCMSPageTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCMSPageTest.xml @@ -10,11 +10,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="VerifyTinyMCEv4IsNativeWYSIWYGOnCMSPageTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-42046-Apply new WYSIWYG on CMS Page"/> <group value="Cms"/> - <title value="Admin see TinyMCEv4.6 is native WYSIWYG on CMS Page"/> - <description value="Admin see TinyMCEv4.6 is native WYSIWYG on CMS Page"/> + <title value="Admin should see TinyMCEv4.6 is the native WYSIWYG on CMS Page"/> + <description value="Admin should see TinyMCEv4.6 is the native WYSIWYG on CMS Page"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84182 "/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Data/ConfigurableProductData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Data/ConfigurableProductData.xml index 0a2429fa8f9e5..70e758a51409d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Data/ConfigurableProductData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Data/ConfigurableProductData.xml @@ -34,6 +34,19 @@ <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> <requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity> </entity> + <entity name="ApiConfigurableProductWithDescription" type="product"> + <data key="sku" unique="suffix">api-configurable-product</data> + <data key="type_id">configurable</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">API Configurable Product</data> + <data key="urlKey" unique="suffix">api-configurable-product</data> + <data key="status">1</data> + <data key="quantity">100</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> + </entity> <entity name="ConfigurableProductAddChild" type="ConfigurableProductAddChild"> <var key="sku" entityKey="sku" entityType="product" /> <var key="childSku" entityKey="sku" entityType="product2"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Section/StorefrontProductInfoMainSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Section/StorefrontProductInfoMainSection.xml index cebb76e68a6cc..45bf866551319 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Section/StorefrontProductInfoMainSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Section/StorefrontProductInfoMainSection.xml @@ -14,5 +14,8 @@ <element name="productAttributeOptions1" type="select" selector="#product-options-wrapper div[tabindex='0'] option"/> <element name="productAttributeOptionsSelectButton" type="select" selector="#product-options-wrapper .super-attribute-select"/> <element name="productAttributeOptionsError" type="text" selector="//div[@class='mage-error']"/> + <!-- Parameter is the order number of the attribute on the page (1 is the newest) --> + <element name="nthAttributeOnPage" type="block" selector="tr:nth-of-type({{numElement}}) .data" parameterized="true"/> + <element name="stockIndication" type="block" selector=".stock" /> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/AdminConfigurableProductOutOfStockTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/AdminConfigurableProductOutOfStockTest.xml new file mode 100644 index 0000000000000..96651e303c5f2 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/AdminConfigurableProductOutOfStockTest.xml @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminConfigurableProductOutOfStockTest"> + <annotations> + <features value="ConfigurableProduct"/> + <stories value="Product visibility when in stock/out of stock"/> + <title value="Configurable Product goes 'Out of Stock' if all associated Simple Products are 'Out of Stock'"/> + <description value="Configurable Product goes 'Out of Stock' if all associated Simple Products are 'Out of Stock'"/> + <testCaseId value="MC-181"/> + <group value="ConfigurableProduct"/> + </annotations> + <before> + <!-- TODO: This should be converted to an actionGroup once MQE-993 is fixed. --> + <!-- Create the category to put the product in --> + <createData entity="ApiCategory" stepKey="createCategory"/> + + <!-- Create the configurable product based on the data in the /data folder --> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + + <!-- Make the configurable product have two options, that are children of the default attribute set --> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + + <!-- Create the 2 children that will be a part of the configurable product --> + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Assign the two products to the configurable product --> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + + <!-- log in --> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + </before> + + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + </after> + + <!-- Check to make sure that the configurable product shows up as in stock --> + <amOnPage url="/{{ApiConfigurableProduct.urlKey}}2.html" stepKey="goToConfigProductPage"/> + <waitForPageLoad stepKey="waitForStoreFrontLoad"/> + <see stepKey="lookForOutOfStock" selector="{{StorefrontProductInfoMainSection.stockIndication}}" userInput="IN STOCK" /> + + <!-- Find the first simple product that we just created using the product grid and go to its page--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage"/> + <waitForPageLoad stepKey="waitForAdminProductGridLoad"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> + <actionGroup ref="filterProductGridBySku" stepKey="findCreatedProduct"> + <argument name="product" value="ApiSimpleOne"/> + </actionGroup> + <waitForPageLoad stepKey="waitForFiltersToBeApplied"/> + <click selector="{{AdminProductGridSection.firstRow}}" stepKey="clickOnProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + + <!-- Edit the quantity of the simple first product as 0 --> + <fillField selector="{{AdminProductFormSection.productQuantity}}" userInput="0" stepKey="fillProductQuantity"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct"/> + <waitForPageLoad stepKey="waitForProductPageSaved"/> + + <!-- Check to make sure that the configurable product shows up as in stock --> + <amOnPage url="/{{ApiConfigurableProduct.urlKey}}2.html" stepKey="goToConfigProductPage2"/> + <waitForPageLoad stepKey="waitForStoreFrontLoad2"/> + <see stepKey="lookForOutOfStock2" selector="{{StorefrontProductInfoMainSection.stockIndication}}" userInput="IN STOCK"/> + + <!-- Find the second simple product that we just created using the product grid and go to its page--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage2"/> + <waitForPageLoad stepKey="waitForAdminProductGridLoad2"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial2"/> + <actionGroup ref="filterProductGridBySku" stepKey="findCreatedProduct2"> + <argument name="product" value="ApiSimpleTwo"/> + </actionGroup> + <waitForPageLoad stepKey="waitForFiltersToBeApplied2"/> + <click selector="{{AdminProductGridSection.firstRow}}" stepKey="clickOnProductPage2"/> + <waitForPageLoad stepKey="waitForProductPageLoad2"/> + + <!-- Edit the quantity of the second simple product as 0 --> + <fillField selector="{{AdminProductFormSection.productQuantity}}" userInput="0" stepKey="fillProductQuantity2"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct2"/> + <waitForPageLoad stepKey="waitForProductPageSaved2"/> + + <!-- Check to make sure that the configurable product shows up as out of stock --> + <amOnPage url="/{{ApiConfigurableProduct.urlKey}}2.html" stepKey="goToConfigProductPage3"/> + <waitForPageLoad stepKey="waitForStoreFrontLoad3"/> + <see stepKey="lookForOutOfStock3" selector="{{StorefrontProductInfoMainSection.stockIndication}}" userInput="OUT OF STOCK"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/AdminConfigurableProductUpdateAttributeTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/AdminConfigurableProductUpdateAttributeTest.xml new file mode 100644 index 0000000000000..a8eabb3b56a39 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/AdminConfigurableProductUpdateAttributeTest.xml @@ -0,0 +1,271 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminConfigurableProductUpdateAttributeTest"> + <annotations> + <features value="ConfigurableProduct"/> + <stories value="Edit a configurable product in admin"/> + <title value="Admin should be able to update existing attributes of a configurable product"/> + <description value="Admin should be able to update existing attributes of a configurable product"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-179"/> + <group value="ConfigurableProduct"/> + </annotations> + + <before> + <!-- Create the attribute we will be modifying --> + <createData entity="productAttributeWithTwoOptions" stepKey="createModifiableProductAttribute"/> + + <!-- Create the two attributes the product will have --> + <createData entity="productAttributeOption1" stepKey="createModifiableProductAttributeOption1"> + <requiredEntity createDataKey="createModifiableProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createModifiableProductAttributeOption2"> + <requiredEntity createDataKey="createModifiableProductAttribute"/> + </createData> + + <!-- Add the product to the default set --> + <createData entity="AddToDefaultSet" stepKey="createModifiableAddToAttributeSet"> + <requiredEntity createDataKey="createModifiableProductAttribute"/> + </createData> + + <!-- TODO: This should be converted to an actionGroup once MQE-993 is fixed. --> + <!-- Create the category the product will be a part of --> + <createData entity="ApiCategory" stepKey="createCategory"/> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + + <!-- Create the two attributes the product will have --> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + + <!-- Add the product to the default set --> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + + <!-- Get the two attributes --> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + + <!-- Create the two children product --> + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Create the two configurable product with both children --> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + + <!-- login --> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + </before> + + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + + <!-- Delete everything that was created in the before block --> + <deleteData createDataKey="createCategory" stepKey="deleteCatagory" /> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createModifiableProductAttribute" stepKey="deleteModifiableProductAttribute"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + </after> + + <!-- Get the current option of the attribute before it was changed --> + <amOnPage url="/{{ApiConfigurableProduct.urlKey}}2.html" stepKey="goToConfigProductPage"/> + <waitForPageLoad stepKey="waitForStoreFrontProductPageLoad"/> + + <grabTextFrom stepKey="getBeforeOption" selector="{{StorefrontProductInfoMainSection.nthAttributeOnPage('1')}}"/> + + <!-- Find the product that we just created using the product grid --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage"/> + <waitForPageLoad stepKey="waitForAdminProductPageLoad"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> + <actionGroup ref="filterProductGridBySku" stepKey="findCreatedProduct"> + <argument name="product" value="ApiConfigurableProduct"/> + </actionGroup> + <waitForPageLoad stepKey="waitForProductFilterLoad"/> + + <click selector="{{AdminProductGridSection.firstRow}}" stepKey="clickOnProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + + <!-- change the option on the first attribute --> + <selectOption stepKey="clickFirstAttribute" selector="{{ModifyAttributes.nthExistingAttribute($$createModifiableProductAttribute.default_frontend_label$$)}}" userInput="option1"/> + + <!-- Save the product --> + <click stepKey="saveProductAttribute" selector="{{AdminProductFormActionSection.saveButton}}"/> + <see stepKey="assertSuccess" selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product."/> + + <!-- Go back to the configurable product page and check to see if it has changed --> + <amOnPage url="/{{ApiConfigurableProduct.urlKey}}2.html" stepKey="goToConfigProductPage2"/> + <waitForPageLoad stepKey="waitForStoreFrontProductPageLoad2"/> + <grabTextFrom stepKey="getCurrentOption" selector="{{StorefrontProductInfoMainSection.nthAttributeOnPage('1')}}"/> + <assertNotEquals expected="{$getBeforeOption}" expectedType="string" actual="{$getCurrentOption}" actualType="string" stepKey="assertNotEquals"/> + + </test> + + <test name="AdminConfigurableProductUpdateChildAttributeTest"> + <annotations> + <features value="ConfigurableProduct"/> + <stories value="Edit a configurable product in admin"/> + <title value="Admin should be able to update existing attributes of child products of a configurable product"/> + <description value="Admin should be able to update existing attributes of child products of a configurable product"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-288"/> + <group value="ConfigurableProduct"/> + </annotations> + + <before> + + <!-- TODO: This should be converted to an actionGroup once MQE-993 is fixed. --> + <!-- Create the category the product will be a part of --> + <createData entity="ApiCategory" stepKey="createCategory"/> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + + <!-- Create the two attributes the product will have --> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + + <!-- Add the product to the default set --> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + + <!-- Get the two attributes --> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + + <!-- Create the two children product --> + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Create the two configurable product with both children --> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + + <!-- login --> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + </before> + + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + + <!-- Delete everything that was created in the before block --> + <deleteData createDataKey="createCategory" stepKey="deleteCatagory" /> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + </after> + + <!-- Find the product that we just created using the product grid --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage"/> + <waitForPageLoad stepKey="waitForAdminProductPageLoad"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> + <actionGroup ref="filterProductGridBySku" stepKey="findCreatedProduct"> + <argument name="product" value="ApiConfigurableProduct"/> + </actionGroup> + <waitForPageLoad stepKey="waitForProductFilterLoad"/> + + <click selector="{{AdminProductGridSection.firstRow}}" stepKey="clickOnProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + + <!-- Open the wizard for editing configurations and fill out a new attribute --> + <click stepKey="clickEditConfig" selector="{{AdminProductFormConfigurationsSection.createConfigurations}}"/> + <waitForPageLoad stepKey="waitForEditConfig"/> + <click stepKey="clickNextWizard" selector="{{AdminCreateProductConfigurationsPanel.next}}"/> + <click stepKey="createNewValue" selector="{{AdminCreateProductConfigurationsPanel.createNewValue}}"/> + <fillField stepKey="fillNewAttribute" selector="{{AdminCreateProductConfigurationsPanel.attributeName}}" userInput="simple"/> + <click stepKey="confirmNewAttribute" selector="{{AdminCreateProductConfigurationsPanel.saveAttribute}}"/> + <click stepKey="clickNextWizard2" selector="{{AdminCreateProductConfigurationsPanel.next}}"/> + + <!-- Give the product a price and quantity --> + <click stepKey="click" selector="{{AdminCreateProductConfigurationsPanel.applySingleQuantityToEachSkus}}"/> + <fillField stepKey="fillProductQuantity" selector="{{AdminCreateProductConfigurationsPanel.quantity}}" userInput="{{_defaultProduct.quantity}}"/> + <click stepKey="clickNextWizard3" selector="{{AdminCreateProductConfigurationsPanel.next}}"/> + <click stepKey="clickGenerateProducts" selector="{{AdminCreateProductConfigurationsPanel.next}}"/> + + <!-- Save the product --> + <waitForPageLoad stepKey="waitForGeneration"/> + <click stepKey="saveProductAttribute" selector="{{AdminProductFormActionSection.saveButton}}"/> + <see stepKey="assertSuccess" selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product."/> + + <!-- Check to make sure the created product has appeared on the configurable product storefront --> + <amOnPage url="/{{ApiConfigurableProduct.urlKey}}2.html" stepKey="goToConfigProductPage"/> + <waitForPageLoad stepKey="waitForStorefront"/> + <selectOption stepKey="clickFirstAttribute" selector="{{ModifyAttributes.nthExistingAttribute($$createConfigProductAttribute.default_frontend_label$$)}}" userInput="simple"/> + <waitForPageLoad stepKey="waitForPageExecution"/> + <see stepKey="checkPrice" selector="{{StorefrontProductInfoMainSection.productPrice}}" userInput="0.00"/> + <waitForPageLoad stepKey="waitForStoreFrontProductPageLoad"/> + + <!-- Find the simple product that we just created using the product grid and delete it --> + <actionGroup ref="deleteProductBySku" stepKey="findCreatedProduct2"> + <argument name="sku" value="{{ApiConfigurableProduct.sku}}2-simple"/> + </actionGroup> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/AdminRelatedProductsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/AdminRelatedProductsTest.xml index 0d773cb6df666..50fb6bdf866d8 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/AdminRelatedProductsTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/AdminRelatedProductsTest.xml @@ -10,7 +10,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminRelatedProductsTest"> <annotations> - <features value="Promote Products as Related"/> + <features value="ConfigurableProduct"/> <stories value="Promote Products as Related"/> <title value="Admin should be able to promote products as related"/> <description value="Admin should be able to promote products as related"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/ConfigurableProductPriceAdditionalStoreViewTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/ConfigurableProductPriceAdditionalStoreViewTest.xml index 306a20124c5ca..609ccbb4c27a2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/ConfigurableProductPriceAdditionalStoreViewTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProduct/Test/ConfigurableProductPriceAdditionalStoreViewTest.xml @@ -73,13 +73,22 @@ <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <actionGroup ref="ResetWebUrlOptions" stepKey="resetUrlOption"/> - <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteWebsite"/> + <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteSecondWebsite"> + <argument name="websiteName" value="Second Website"/> + </actionGroup> <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> </after> <actionGroup ref="EnableWebUrlOptions" stepKey="addStoreCodeToUrls"/> - <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="addnewWebsite"/> - <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="addNewStoreGroup"/> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="addNewWebsite"> + <argument name="newWebsiteName" value="Second Website"/> + <argument name="websiteCode" value="second_website"/> + </actionGroup> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="addNewStoreGroup"> + <argument name="website" value="Second Website"/> + <argument name="storeGroupName" value="Second Store"/> + <argument name="storeGroupCode" value="second_store"/> + </actionGroup> <!--Create Store view --> <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="amOnAdminSystemStorePage"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml index ef00e2d72f100..04c50378c6607 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml @@ -24,4 +24,25 @@ <see stepKey="seeLastName" userInput="{{Customer.lastname}}" selector="{{StorefrontCustomerDashboardAccountInformationSection.ContactInformation}}" /> <see stepKey="seeEmail" userInput="{{Customer.email}}" selector="{{StorefrontCustomerDashboardAccountInformationSection.ContactInformation}}" /> </actionGroup> + + <actionGroup name="EnterCustomerAddressInfo"> + <arguments> + <argument name="Address"/> + </arguments> + + <amOnPage url="customer/address/new/" stepKey="goToAddressPage"/> + <waitForPageLoad stepKey="waitForAddressPage"/> + <fillField stepKey="fillFirstName" selector="{{StorefrontCustomerAddressSection.firstName}}" userInput="{{Address.firstname}}"/> + <fillField stepKey="fillLastName" selector="{{StorefrontCustomerAddressSection.lastName}}" userInput="{{Address.lastname}}"/> + <fillField stepKey="fillCompany" selector="{{StorefrontCustomerAddressSection.company}}" userInput="{{Address.company}}"/> + <fillField stepKey="fillPhoneNumber" selector="{{StorefrontCustomerAddressSection.phoneNumber}}" userInput="{{Address.telephone}}"/> + <fillField stepKey="fillStreetAddress1" selector="{{StorefrontCustomerAddressSection.streetAddress1}}" userInput="{{Address.street[0]}}"/> + <fillField stepKey="fillStreetAddress2" selector="{{StorefrontCustomerAddressSection.streetAddress2}}" userInput="{{Address.street[1]}}"/> + <fillField stepKey="fillCityName" selector="{{StorefrontCustomerAddressSection.city}}" userInput="{{Address.city}}"/> + <selectOption stepKey="selectState" selector="{{StorefrontCustomerAddressSection.stateProvince}}" userInput="{{Address.state}}"/> + <fillField stepKey="fillZip" selector="{{StorefrontCustomerAddressSection.zip}}" userInput="{{Address.postcode}}"/> + <selectOption stepKey="selectCounty" selector="{{StorefrontCustomerAddressSection.country}}" userInput="{{Address.country_id}}"/> + + <click stepKey="saveAddress" selector="{{StorefrontCustomerAddressSection.saveAddress}}"/> + </actionGroup> </actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/AddressData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/AddressData.xml index 5f89a3ce9aaa7..efa7a1cdb5e69 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/AddressData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/AddressData.xml @@ -49,4 +49,38 @@ <data key="default_shipping">Yes</data> <requiredEntity type="region">RegionTX</requiredEntity> </entity> + <entity name="US_Address_NY" type="address"> + <data key="firstname">John</data> + <data key="lastname">Doe</data> + <data key="company">368</data> + <array key="street"> + <item>368 Broadway St.</item> + <item>113</item> + </array> + <data key="city">New York</data> + <data key="state">New York</data> + <data key="country_id">US</data> + <data key="postcode">10001</data> + <data key="telephone">512-345-6789</data> + <data key="default_billing">Yes</data> + <data key="default_shipping">Yes</data> + <requiredEntity type="region">RegionNY</requiredEntity> + </entity> + <entity name="US_Address_CA" type="address"> + <data key="firstname">John</data> + <data key="lastname">Doe</data> + <data key="company">Magento</data> + <array key="street"> + <item>7700 West Parmer Lane</item> + <item>113</item> + </array> + <data key="city">Los Angeles</data> + <data key="state">California</data> + <data key="country_id">US</data> + <data key="postcode">90001</data> + <data key="telephone">512-345-6789</data> + <data key="default_billing">Yes</data> + <data key="default_shipping">Yes</data> + <requiredEntity type="region">RegionCA</requiredEntity> + </entity> </entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/CustomerData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/CustomerData.xml index 9dee9a1c245f5..4d65f2aa56b65 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/CustomerData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/CustomerData.xml @@ -45,6 +45,32 @@ <data key="website_id">0</data> <requiredEntity type="address">US_Address_TX</requiredEntity> </entity> + <entity name="Simple_US_Customer_NY" type="customer"> + <data key="group_id">0</data> + <data key="default_billing">true</data> + <data key="default_shipping">true</data> + <data key="email" unique="prefix">John.Doe@example.com</data> + <data key="firstname">John</data> + <data key="lastname">Doe</data> + <data key="fullname">John Doe</data> + <data key="password">pwdTest123!</data> + <data key="store_id">0</data> + <data key="website_id">0</data> + <requiredEntity type="address">US_Address_NY</requiredEntity> + </entity> + <entity name="Simple_US_Customer_CA" type="customer"> + <data key="group_id">0</data> + <data key="default_billing">true</data> + <data key="default_shipping">true</data> + <data key="email" unique="prefix">John.Doe@example.com</data> + <data key="firstname">John</data> + <data key="lastname">Doe</data> + <data key="fullname">John Doe</data> + <data key="password">pwdTest123!</data> + <data key="store_id">0</data> + <data key="website_id">0</data> + <requiredEntity type="address">US_Address_CA</requiredEntity> + </entity> <entity name="Simple_US_Customer_For_Update" type="customer"> <var key="id" entityKey="id" entityType="customer"/> <data key="firstname">Jane</data> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/CustomerGroupData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/CustomerGroupData.xml index 61e0c05ea82a6..5279f4216898e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/CustomerGroupData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/CustomerGroupData.xml @@ -13,4 +13,9 @@ <data key="tax_class_id">3</data> <data key="tax_class_name">Retail Customer</data> </entity> + <entity name="DefaultCustomerGroup" type="customerGroup"> + <array key="group_names"> + <item>General</item> + </array> + </entity> </entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/RegionData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/RegionData.xml index b69235531dc3c..95e0362e84d71 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/RegionData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Data/RegionData.xml @@ -17,4 +17,14 @@ <data key="region_code">TX</data> <data key="region_id">1</data> </entity> + <entity name="RegionCA" type="region"> + <data key="region">California</data> + <data key="region_code">CA</data> + <data key="region_id">2</data> + </entity> + <entity name="RegionNY" type="region"> + <data key="region">New York</data> + <data key="region_code">NY</data> + <data key="region_id">3</data> + </entity> </entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Section/AdminCustomerAccountInformationSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Section/AdminCustomerAccountInformationSection.xml index 362254f8a28dc..4c72be870f161 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Section/AdminCustomerAccountInformationSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Section/AdminCustomerAccountInformationSection.xml @@ -13,5 +13,6 @@ <element name="firstName" type="input" selector="input[name='customer[firstname]']"/> <element name="lastName" type="input" selector="input[name='customer[lastname]']"/> <element name="email" type="input" selector="input[name='customer[email]']"/> + <element name="group" type="select" selector="[name='customer[group_id]']"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Section/StorefrontCustomerDashboardAccountInformationSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Section/StorefrontCustomerDashboardAccountInformationSection.xml index 4e8ce1ffaf202..001dde0b98afd 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Section/StorefrontCustomerDashboardAccountInformationSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Section/StorefrontCustomerDashboardAccountInformationSection.xml @@ -11,4 +11,17 @@ <section name="StorefrontCustomerDashboardAccountInformationSection"> <element name="ContactInformation" type="textarea" selector=".box.box-information .box-content"/> </section> + <section name="StorefrontCustomerAddressSection"> + <element name="firstName" type="input" selector="#firstname"/> + <element name="lastName" type="input" selector="#lastname"/> + <element name="company" type="input" selector="#company"/> + <element name="phoneNumber" type="input" selector="#telephone"/> + <element name="streetAddress1" type="input" selector="#street_1"/> + <element name="streetAddress2" type="input" selector="#street_2"/> + <element name="city" type="input" selector="#city"/> + <element name="stateProvince" type="select" selector="#region_id"/> + <element name="zip" type="input" selector="#zip"/> + <element name="country" type="select" selector="#country"/> + <element name="saveAddress" type="button" selector="[data-action='save-address']"/> + </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/AdminCreateCustomerTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/AdminCreateCustomerTest.xml index 32f882ce72bdb..17c7b8410b705 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/AdminCreateCustomerTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/AdminCreateCustomerTest.xml @@ -10,15 +10,14 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateCustomerTest"> <annotations> - <features value="Customer Creation"/> + <features value="Customer"/> <stories value="Create a Customer via the Admin"/> - <title value="You should be able to create a customer in the Admin back-end."/> - <description value="You should be able to create a customer in the Admin back-end."/> + <title value="Admin should be able to create a customer"/> + <description value="Admin should be able to create a customer"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-72095"/> <group value="customer"/> <group value="create"/> - <group value="skip"/> </annotations> <after> <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/StorefrontCreateCustomerTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/StorefrontCreateCustomerTest.xml index 6c155f8c1dbfe..92893e76d42c2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/StorefrontCreateCustomerTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/StorefrontCreateCustomerTest.xml @@ -10,10 +10,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="StorefrontCreateCustomerTest"> <annotations> - <features value="Customer Creation"/> + <features value="Customer"/> <stories value="Create a Customer via the Storefront"/> - <title value="You should be able to create a customer via the storefront"/> - <description value="You should be able to create a customer via the storefront."/> + <title value="Admin should be able to create a customer via the storefront"/> + <description value="Admin should be able to create a customer via the storefront"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-23546"/> <group value="customer"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/StorefrontPersistedCustomerLoginTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/StorefrontPersistedCustomerLoginTest.xml index 9e23ffa653630..27e4db958cbfe 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/StorefrontPersistedCustomerLoginTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/Test/StorefrontPersistedCustomerLoginTest.xml @@ -10,11 +10,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="StorefrontPersistedCustomerLoginTest"> <annotations> - - <features value="Persisted customer can login from storefront."/> - <stories value="Persisted customer can login from storefront."/> - <title value="Persisted customer can login from storefront."/> - <description value="Persisted customer can login from storefront."/> + <features value="Customer"/> + <stories value="Login"/> + <title value="Persisted customer should be able to login from storefront"/> + <description value="Persisted customer should be able to login from storefront"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-72103"/> <group value="customer"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Data/LinkData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Data/LinkData.xml index 6276f340f85a6..1498f4b96b3ab 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Data/LinkData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Data/LinkData.xml @@ -41,4 +41,13 @@ <data key="file_type">URL</data> <data key="file">https://static.magento.com/sites/all/themes/mag_redesign/images/magento-logo.svg</data> </entity> + <entity name="ApiDownloadableLink" type="downloadable_link"> + <data key="title" unique="suffix">Api Downloadable Link</data> + <data key="price">2.00</data> + <data key="link_type">url</data> + <data key="shareable">No</data> + <data key="number_of_downloads">1000</data> + <data key="sort_order">0</data> + <data key="link_url">https://static.magento.com/sites/all/themes/mag_redesign/images/magento-logo.svg</data> + </entity> </entities> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Data/ProductData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Data/ProductData.xml index 427f2577a8ab9..f71ebd481a97d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Data/ProductData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Data/ProductData.xml @@ -19,4 +19,19 @@ <data key="status">1</data> <data key="urlKey" unique="suffix">downloadableproduct</data> </entity> + <entity name="ApiDownloadableProduct" type="product"> + <data key="sku" unique="suffix">api-downloadable-product</data> + <data key="type_id">downloadable</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">Api Downloadable Product</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">api-downloadable-product</data> + <data key="status">1</data> + <data key="quantity">100</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> + <requiredEntity type="downloadable_link">apiDownloadableLink</requiredEntity> + </entity> </entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Metadata/downloadable_link-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Metadata/downloadable_link-meta.xml new file mode 100644 index 0000000000000..dc86c4e8d7957 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Metadata/downloadable_link-meta.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="CreateDownloadableLink" dataType="downloadable_link" type="create" auth="adminOauth" url="/V1/products/{sku}/downloadable-links" method="POST"> + <contentType>application/json</contentType> + <object dataType="downloadable_link" key="link"> + <field key="title">string</field> + <field key="sort_order">integer</field> + <field key="is_shareable">integer</field> + <field key="price">number</field> + <field key="number_of_downloads">integer</field> + <field key="link_type">string</field> + <field key="link_file">string</field> + <field key="link_file_content">link_file_content</field> + <field key="file_data">string</field> + <field key="link_url">string</field> + <field key="sample_type">string</field> + <field key="sample_file">string</field> + <field key="sample_file_content">sample_file_content</field> + <field key="sample_url">string</field> + </object> + <field key="isGlobalScopeContent">boolean</field> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Metadata/link_file_content-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Metadata/link_file_content-meta.xml new file mode 100644 index 0000000000000..72f643e06800d --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Metadata/link_file_content-meta.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="CreateLinkFileContent" dataType="link_file_content" type="create"> + <field key="file_data">string</field> + <field key="name">string</field> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Metadata/sample_file_content-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Metadata/sample_file_content-meta.xml new file mode 100644 index 0000000000000..144ce67bb25bb --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Downloadable/Metadata/sample_file_content-meta.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="CreateSampleFileContent" dataType="sample_file_content" type="create"> + <field key="file_data">string</field> + <field key="name">string</field> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/GroupedProductData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/GroupedProductData.xml index 019b0d24dec52..9960d698a7861 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/GroupedProductData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/GroupedProductData.xml @@ -17,4 +17,15 @@ <data key="urlKey" unique="suffix">groupedproduct</data> <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> </entity> + <entity name="ApiGroupedProduct" type="product3"> + <data key="sku" unique="suffix">api-grouped-product</data> + <data key="type_id">grouped</data> + <data key="attribute_set_id">4</data> + <data key="name" unique="suffix">Api Grouped Product</data> + <data key="status">1</data> + <data key="urlKey" unique="suffix">api-grouped-product</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> + </entity> </entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/ProductLinkData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/ProductLinkData.xml new file mode 100644 index 0000000000000..9a5df1e379a86 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/ProductLinkData.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="ProductLinkSimple1" type="product_link"> + <var key="sku" entityKey="sku" entityType="product3"/> + <var key="linked_product_sku" entityKey="sku" entityType="product"/> + <data key="link_type">associated</data> + <data key="linked_product_type">simple</data> + <data key="position">1</data> + <requiredEntity type="product_link_extension_attribute">Qty1000</requiredEntity> + </entity> + <entity name="ProductLinkSimple2" type="product_link"> + <var key="sku" entityKey="sku" entityType="product3"/> + <var key="linked_product_sku" entityKey="sku" entityType="product"/> + <data key="link_type">associated</data> + <data key="linked_product_type">simple</data> + <data key="position">2</data> + <requiredEntity type="product_link_extension_attribute">Qty1000</requiredEntity> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/ProductLinkExtensionAttributeData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/ProductLinkExtensionAttributeData.xml new file mode 100644 index 0000000000000..5f5dcb3a0ef4f --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/ProductLinkExtensionAttributeData.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="Qty1000" type="product_link_extension_attribute"> + <data key="qty">1000</data> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/ProductLinksData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/ProductLinksData.xml new file mode 100644 index 0000000000000..523517aa70080 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/GroupedProduct/Data/ProductLinksData.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="OneSimpleProductLink" type="product_links"> + <requiredEntity type="product_link">ProductLinkSimple1</requiredEntity> + </entity> + <entity name="OneMoreSimpleProductLink" type="product_links"> + <requiredEntity type="product_link">ProductLinkSimple2</requiredEntity> + </entity> + <entity name="TwoSimpleProductLinks" type="product_links"> + <array key="items"> + <item>ProductLinkSimple1</item> + <item>ProductLinkSimple2</item> + </array> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddImageToWYSIWYGNewsletterTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddImageToWYSIWYGNewsletterTest.xml index bb27cfa5bb809..118d774ec6afc 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddImageToWYSIWYGNewsletterTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddImageToWYSIWYGNewsletterTest.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddImageToWYSIWYGNewsletterTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Newsletter"/> <stories value="MAGETWO-47309-Apply new WYSIWYG in Newsletter"/> <group value="Newsletter"/> <title value="Admin should be able to add image to WYSIWYG content of Newsletter"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddVariableToWYSIWYGNewsletterTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddVariableToWYSIWYGNewsletterTest.xml index 312aef30c43bd..2ad2709c8fb8e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddVariableToWYSIWYGNewsletterTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddVariableToWYSIWYGNewsletterTest.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddVariableToWYSIWYGNewsletterTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Newsletter"/> <stories value="MAGETWO-42158-Variable with WYSIWYG"/> <group value="Newsletter"/> <title value="Admin should be able to add variable to WYSIWYG Editor of Newsletter"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml index 5395b0563740a..bfa8fc40eeb20 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml @@ -9,11 +9,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminAddWidgetToWYSIWYGNewsletterTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Newsletter"/> <stories value="MAGETWO-47309-Apply new WYSIWYG in Newsletter"/> <group value="Newsletter"/> - <title value="You should be able to add widget to WYSIWYG Editor of Newsletter"/> - <description value="You should be able to add widget to WYSIWYG Editor Newsletter"/> + <title value="Admin should be able to add widget to WYSIWYG Editor of Newsletter"/> + <description value="Admin should be able to add widget to WYSIWYG Editor Newsletter"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84682"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnNewsletterTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnNewsletterTest.xml index 1fe7db5e3f052..b7b9e21adde7f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnNewsletterTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnNewsletterTest.xml @@ -9,11 +9,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="VerifyTinyMCEv4IsNativeWYSIWYGOnNewsletterTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Newsletter"/> <stories value="MAGETWO-47309-Apply new WYSIWYG in Newsletter"/> <group value="Newsletter"/> - <title value="Admin see TinyMCEv4.6 is native WYSIWYG on Newsletter"/> - <description value="Admin see TinyMCEv4.6 is native WYSIWYG on Newsletter"/> + <title value="Admin should see TinyMCEv4.6 is the native WYSIWYG on Newsletter"/> + <description value="Admin should see TinyMCEv4.6 is the native WYSIWYG on Newsletter"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84683"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/ActionGroup/ClearPageCacheActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/ActionGroup/ClearPageCacheActionGroup.xml new file mode 100644 index 0000000000000..f09ca7f1fe025 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/ActionGroup/ClearPageCacheActionGroup.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="ClearPageCacheActionGroup"> + <amOnPage url="{{_ENV.MAGENTO_BACKEND_NAME}}/admin/cache/" stepKey="goToCacheManagementPage" /> + <waitForPageLoad stepKey="waitForPageLoad"/> + <click selector="{{AdminCacheManagementSection.actionDropDown}}" stepKey="actionSelection"/> + <click selector="{{AdminCacheManagementSection.refreshOption}}" stepKey="selectRefreshOption"/> + <click selector="{{AdminCacheManagementSection.pageCacheRowCheckbox}}" stepKey="selectPageCacheRowCheckbox"/> + <click selector="{{AdminCacheManagementSection.submit}}" stepKey="clickSubmit"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/Section/AdminCacheManagementSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/Section/AdminCacheManagementSection.xml index cb33e25c9ce6a..d5d1e7bf65cb8 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/Section/AdminCacheManagementSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/PageCache/Section/AdminCacheManagementSection.xml @@ -10,6 +10,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="AdminCacheManagementSection"> <element name="FlushMagentoCache" type="button" selector="#flush_magento"/> + <element name="actionDropDown" type="multiselect" selector="//*[@id='cache_grid_massaction-select']//option[contains(., 'Action')]" timeout="30"/> + <element name="refreshOption" type="multiselect" selector="//*[@id='cache_grid_massaction-select']//option[@value='refresh']" timeout="30"/> + <element name="pageCacheRowCheckbox" type="checkbox" selector="//td[contains(., 'Page Cache')]/..//input[@type='checkbox']"/> + <element name="submit" type="button" selector="//button[@title='Submit']" timeout="30"/> </section> </sections> - diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/Data/PersistentData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/Data/PersistentData.xml new file mode 100644 index 0000000000000..4ba2e1ae73824 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/Data/PersistentData.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="PersistentConfigDefault" type="persistent_config_state"> + <requiredEntity type="persistent_options_enabled">persistentDefaultState</requiredEntity> + </entity> + <entity name="persistentDefaultState" type="persistent_options_enabled"> + <data key="value">0</data> + </entity> + + <entity name="PersistentConfigEnabled" type="persistent_config_state"> + <requiredEntity type="persistent_options_enabled">persistentEnabledState</requiredEntity> + </entity> + <entity name="persistentEnabledState" type="persistent_options_enabled"> + <data key="value">1</data> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/Metadata/persistent_config-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/Metadata/persistent_config-meta.xml new file mode 100644 index 0000000000000..69a835aa703eb --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/Metadata/persistent_config-meta.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="CreatePersistentConfigState" dataType="persistent_config_state" type="create" auth="adminFormKey" url="/admin/system_config/save/section/persistent/" method="POST"> + <object key="groups" dataType="persistent_config_state"> + <object key="options" dataType="persistent_config_state"> + <object key="fields" dataType="persistent_config_state"> + <object key="enabled" dataType="persistent_options_enabled"> + <field key="value">string</field> + </object> + </object> + </object> + </object> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/Test/GuestCheckoutWithEnabledPersistentTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/Test/GuestCheckoutWithEnabledPersistentTest.xml new file mode 100644 index 0000000000000..f7f76da7d3895 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Persistent/Test/GuestCheckoutWithEnabledPersistentTest.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="GuestCheckoutWithEnabledPersistentTest"> + <annotations> + <features value="Persistent"/> + <title value="Guest Checkout with Enabled Persistent"/> + <description value="Checkout data must be restored after page checkout reload."/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-92453"/> + <group value="persistent"/> + </annotations> + <before> + <createData entity="PersistentConfigEnabled" stepKey="enablePersistent"/> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + </before> + <after> + <createData entity="PersistentConfigDefault" stepKey="setDefaultPersistentState"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + </after> + <!-- Add simple product to cart --> + <actionGroup ref="AddSimpleProductToCart" stepKey="addProductToCart1"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + <!-- Navigate to checkout --> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="navigateToCheckoutFromMinicart"/> + <!-- Fill Shipping Address form --> + <fillField selector="{{CheckoutShippingGuestInfoSection.email}}" userInput="{{CustomerEntityOne.email}}" stepKey="enterEmail"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.firstName}}" userInput="{{CustomerEntityOne.firstname}}" stepKey="enterFirstName"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.lastName}}" userInput="{{CustomerEntityOne.lastname}}" stepKey="enterLastName"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.street}}" userInput="{{CustomerAddressSimple.street[0]}}" stepKey="enterStreet"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.city}}" userInput="{{CustomerAddressSimple.city}}" stepKey="enterCity"/> + <selectOption selector="{{CheckoutShippingGuestInfoSection.region}}" userInput="{{CustomerAddressSimple.state}}" stepKey="selectRegion"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.postcode}}" userInput="{{CustomerAddressSimple.postcode}}" stepKey="enterPostcode"/> + <fillField selector="{{CheckoutShippingGuestInfoSection.telephone}}" userInput="{{CustomerAddressSimple.telephone}}" stepKey="enterTelephone"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <click selector="{{CheckoutShippingGuestInfoSection.firstShippingMethod}}" stepKey="selectFirstShippingMethod"/> + <!-- Check that have the same values after page reload --> + <amOnPage url="{{CheckoutPage.url}}" stepKey="amOnCheckoutShippingInfoPage"/> + <waitForPageLoad stepKey="waitForShippingPageReload"/> + <seeInField selector="{{CheckoutShippingGuestInfoSection.email}}" userInput="{{CustomerEntityOne.email}}" stepKey="seeEmailOnCheckout" /> + <seeInField selector="{{CheckoutShippingGuestInfoSection.firstName}}" userInput="{{CustomerEntityOne.firstName}}" stepKey="seeFirstnameOnCheckout" /> + <seeInField selector="{{CheckoutShippingGuestInfoSection.lastName}}" userInput="{{CustomerEntityOne.lastName}}" stepKey="seeLastnameOnCheckout" /> + <seeInField selector="{{CheckoutShippingGuestInfoSection.street}}" userInput="{{CustomerAddressSimple.street[0]}}" stepKey="seeStreetOnCheckout" /> + <seeInField selector="{{CheckoutShippingGuestInfoSection.city}}" userInput="{{CustomerAddressSimple.city}}" stepKey="seeCityOnCheckout" /> + <seeInField selector="{{CheckoutShippingGuestInfoSection.region}}" userInput="{{CustomerAddressSimple.state}}" stepKey="seeStateOnCheckout" /> + <seeInField selector="{{CheckoutShippingGuestInfoSection.postcode}}" userInput="{{CustomerAddressSimple.postcode}}" stepKey="seePostcodeOnCheckout" /> + <seeInField selector="{{CheckoutShippingGuestInfoSection.telephone}}" userInput="{{CustomerAddressSimple.telephone}}" stepKey="seePhoneOnCheckout" /> + <!-- Click next button to open payment section --> + <click selector="{{CheckoutShippingGuestInfoSection.next}}" stepKey="clickNext"/> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="guestSelectCheckMoneyOrderPayment" /> + <!-- Reload payment section --> + <amOnPage url="{{GuestCheckoutReviewAndPaymentsPage.url}}" stepKey="amOnCheckoutPaymentsPage"/> + <waitForElement selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton2"/> + <!-- Check that address block contains correct information --> + <see selector="{{CheckoutPaymentSection.billingAddress}}" userInput="{{CustomerAddressSimple.firstName}}" stepKey="seeBilllingFirstName" /> + <see selector="{{CheckoutPaymentSection.billingAddress}}" userInput="{{CustomerAddressSimple.lastName}}" stepKey="seeBilllingLastName" /> + <see selector="{{CheckoutPaymentSection.billingAddress}}" userInput="{{CustomerAddressSimple.street[0]}}" stepKey="seeBilllingStreet" /> + <see selector="{{CheckoutPaymentSection.billingAddress}}" userInput="{{CustomerAddressSimple.city}}" stepKey="seeBilllingCity" /> + <see selector="{{CheckoutPaymentSection.billingAddress}}" userInput="{{CustomerAddressSimple.state}}" stepKey="seeBilllingState" /> + <see selector="{{CheckoutPaymentSection.billingAddress}}" userInput="{{CustomerAddressSimple.postcode}}" stepKey="seeBilllingPostcode" /> + <see selector="{{CheckoutPaymentSection.billingAddress}}" userInput="{{CustomerAddressSimple.telephone}}" stepKey="seeBilllingTelephone" /> + <!-- Check that "Ship To" block contains correct information --> + <see selector="{{CheckoutPaymentSection.shipToInfomation}}" userInput="{{CustomerAddressSimple.firstName}}" stepKey="seeShipToFirstName" /> + <see selector="{{CheckoutPaymentSection.shipToInfomation}}" userInput="{{CustomerAddressSimple.lastName}}" stepKey="seeShipToLastName" /> + <see selector="{{CheckoutPaymentSection.shipToInfomation}}" userInput="{{CustomerAddressSimple.street[0]}}" stepKey="seeShipToStreet" /> + <see selector="{{CheckoutPaymentSection.shipToInfomation}}" userInput="{{CustomerAddressSimple.city}}" stepKey="seeShipToCity" /> + <see selector="{{CheckoutPaymentSection.shipToInfomation}}" userInput="{{CustomerAddressSimple.state}}" stepKey="seeShipToState" /> + <see selector="{{CheckoutPaymentSection.shipToInfomation}}" userInput="{{CustomerAddressSimple.postcode}}" stepKey="seeShipToPostcode" /> + <see selector="{{CheckoutPaymentSection.shipToInfomation}}" userInput="{{CustomerAddressSimple.telephone}}" stepKey="seeShipToTelephone" /> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderActionGroup.xml index 7461d9010a024..a4d9f99799e86 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderActionGroup.xml @@ -134,4 +134,14 @@ </arguments> <see selector="{{AdminOrderItemsOrderedSection.productSkuColumn}}" userInput="{{product.sku}}" stepKey="seeSkuInItemsOrdered"/> </actionGroup> + + <!--Cancel order that is in pending status--> + <actionGroup name="cancelPendingOrder"> + <click selector="{{AdminOrderDetailsMainActionsSection.cancel}}" stepKey="clickCancelOrder"/> + <waitForElement selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForCancelConfirmation"/> + <see selector="{{AdminConfirmationModalSection.message}}" userInput="Are you sure you want to cancel this order?" stepKey="seeConfirmationMessage"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmOrderCancel"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You canceled the order." stepKey="seeCancelSuccessMessage"/> + <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Canceled" stepKey="seeOrderStatusCanceled"/> + </actionGroup> </actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderGridActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderGridActionGroup.xml index 75cc560f72734..696cc898a2bc8 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderGridActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/ActionGroup/AdminOrderGridActionGroup.xml @@ -10,11 +10,14 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> <!--Filter order grid by order id field--> <actionGroup name="filterOrderGridById"> + <arguments> + <argument name="orderId" type="string"/> + </arguments> <amOnPage url="{{AdminOrdersPage.url}}" stepKey="navigateToOrderGridPage"/> <waitForPageLoad stepKey="waitForOrderGridLoad"/> <conditionalClick selector="{{AdminOrdersGridSection.clearFilters}}" dependentSelector="{{AdminOrdersGridSection.clearFilters}}" visible="true" stepKey="clearExistingOrderFilters"/> <click selector="{{AdminOrdersGridSection.filters}}" stepKey="openOrderGridFilters"/> - <fillField selector="{{AdminOrdersGridSection.idFilter}}" userInput="$getOrderId" stepKey="fillOrderIdFilter"/> + <fillField selector="{{AdminOrdersGridSection.idFilter}}" userInput="{{orderId}}" stepKey="fillOrderIdFilter"/> <click selector="{{AdminOrdersGridSection.applyFilters}}" stepKey="clickOrderApplyFilters"/> </actionGroup> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Section/AdminOrderTotalSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Section/AdminOrderTotalSection.xml index 5bdcd6a62a897..2434bfaea2638 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Section/AdminOrderTotalSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Section/AdminOrderTotalSection.xml @@ -12,5 +12,6 @@ <element name="subTotal" type="text" selector=".order-subtotal-table tbody tr.col-0>td span.price"/> <element name="grandTotal" type="text" selector=".order-subtotal-table tfoot tr.col-0>td span.price"/> <element name="shippingAndHandling" type="text" selector="//table[contains(@class, 'order-subtotal-table')]//td[normalize-space(.)='Shipping & Handling']/following-sibling::td//span[@class='price']"/> + <element name="total" type="text" selector="//table[contains(@class,'order-subtotal-table')]/tbody/tr/td[contains(text(), '{{total}}')]/following-sibling::td/span/span[contains(@class, 'price')]" parameterized="true"/> </section> </sections> \ No newline at end of file diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminCreateInvoiceTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminCreateInvoiceTest.xml index 2e7af33aa25c4..70bf457b11567 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminCreateInvoiceTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Sales/Test/AdminCreateInvoiceTest.xml @@ -10,10 +10,10 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateInvoiceTest"> <annotations> - <features value="Invoice Creation"/> + <features value="Sales"/> <stories value="Create an Invoice via the Admin"/> - <title value="Create Invoice"/> - <description value="Should be able to create an invoice via the admin."/> + <title value="Admin should be able to create an invoice"/> + <description value="Admin should be able to create an invoice"/> <severity value="MAJOR"/> <testCaseId value="MAGETWO-72096"/> <group value="sales"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/ActionGroup/AdminCartPriceRuleActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/ActionGroup/AdminCartPriceRuleActionGroup.xml new file mode 100644 index 0000000000000..24d881ee6081d --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/ActionGroup/AdminCartPriceRuleActionGroup.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="selectNotLoggedInCustomerGroup"> + <!-- This actionGroup was created to be merged from B2B because B2B has a very different form control here --> + <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Section/PriceRuleConditionsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Section/PriceRuleConditionsSection.xml index 39c6dd6b31968..93ed408ce7a0e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Section/PriceRuleConditionsSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Section/PriceRuleConditionsSection.xml @@ -16,5 +16,9 @@ <element name="treeRoot" type="text" selector=".x-tree-root-ct.x-tree-lines"/> <element name="lastTreeNode" type="text" selector=".x-tree-root-ct.x-tree-lines > div > li > ul > li:last-child div img.x-tree-elbow-end-plus"/> <element name="subcategory4level" type="text" selector=".x-tree-root-ct.x-tree-lines > div > li > ul > li > ul > li > ul > li > ul > li > div img.x-tree-elbow-end-plus"/> + + <element name="ruleParamLink" type="button" selector="//*[@id='conditions__{{var1}}__children']/li[{{var2}}]/span[{{var3}}]/a" parameterized="true"/> + <element name="operatorByIndex" type="input" selector="#conditions__{{var1}}--{{var2}}__operator" parameterized="true"/> + <element name="valueByIndex" type="input" selector="#conditions__{{var1}}--{{var2}}__value" parameterized="true"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleCountry.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleCountry.xml new file mode 100644 index 0000000000000..a6a0d669f3435 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleCountry.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontCartPriceRuleCountry"> + <annotations> + <features value="SalesRule"/> + <stories value="Create cart price rule"/> + <title value="Customer should only see cart price rule discount if condition shipping country"/> + <description value="Customer should only see cart price rule discount if condition shipping country"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-241"/> + <group value="SalesRule"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="_defaultProduct" stepKey="createPreReqProduct"> + <requiredEntity createDataKey="createPreReqCategory"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <actionGroup ref="DeleteCartPriceRuleByName" stepKey="cleanUpRule"> + <argument name="ruleName" value="{{SimpleSalesRule.name}}"/> + </actionGroup> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="createPreReqProduct" stepKey="deletePreReqProduct"/> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + + <!-- Create the rule... --> + <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> + <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> + <!-- Scroll down to fix some flaky behavior... --> + <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> + <waitForElementVisible selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="waitForNewRule"/> + <click selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="clickNewRule"/> + <selectOption selector="{{PriceRuleConditionsSection.rulesDropdown}}" userInput="Shipping Country" stepKey="selectProductAttributes"/> + <waitForPageLoad stepKey="wait1"/> + <click selector="{{PriceRuleConditionsSection.ruleParamLink('1', '1', '2')}}" stepKey="startEditValue"/> + <waitForPageLoad stepKey="wait4"/> + <selectOption selector="{{PriceRuleConditionsSection.valueByIndex('1', '1')}}" userInput="Brazil" stepKey="fillValue"/> + <waitForPageLoad stepKey="wait5"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="9.99" stepKey="fillDiscountAmount"/> + <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> + <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> + + <!-- Add the product we created to our cart --> + <amOnPage url="$$createPreReqProduct.name$$.html" stepKey="goToProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <fillField selector="{{StorefrontProductActionSection.quantity}}" userInput="1" stepKey="fillQuantity"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart"/> + <waitForPageLoad stepKey="waitForAddToCart"/> + + <!-- Should not see the discount yet because we have not set country --> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> + <waitForPageLoad stepKey="waitForCartPage"/> + <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> + <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> + + <!-- See discount if we use valid country --> + <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> + <selectOption selector="{{CheckoutCartSummarySection.country}}" userInput="Brazil" stepKey="fillCountry"/> + <waitForPageLoad stepKey="waitForCountry1"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> + <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$9.99" stepKey="seeDiscountTotal"/> + + <!-- Do not see discount with other country --> + <selectOption selector="{{CheckoutCartSummarySection.country}}" userInput="United States" stepKey="fillCountry2"/> + <waitForPageLoad stepKey="waitForCountry2"/> + <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount2"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRulePostcode.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRulePostcode.xml new file mode 100644 index 0000000000000..97936382e60e0 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRulePostcode.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontCartPriceRulePostcode"> + <annotations> + <features value="SalesRule"/> + <stories value="Create cart price rule"/> + <title value="Customer should only see cart price rule discount if condition shipping postcode"/> + <description value="Customer should only see cart price rule discount if condition shipping postcode"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-238"/> + <group value="SalesRule"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="_defaultProduct" stepKey="createPreReqProduct"> + <requiredEntity createDataKey="createPreReqCategory"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <actionGroup ref="DeleteCartPriceRuleByName" stepKey="cleanUpRule"> + <argument name="ruleName" value="{{SimpleSalesRule.name}}"/> + </actionGroup> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="createPreReqProduct" stepKey="deletePreReqProduct"/> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + + <!-- Create the rule... --> + <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> + <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> + <!-- Scroll down to fix some flaky behavior... --> + <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> + <waitForElementVisible selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="waitForNewRule"/> + <click selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="clickNewRule"/> + <selectOption selector="{{PriceRuleConditionsSection.rulesDropdown}}" userInput="Shipping Postcode" stepKey="selectProductAttributes"/> + <waitForPageLoad stepKey="wait1"/> + <click selector="{{PriceRuleConditionsSection.ruleParamLink('1', '1', '1')}}" stepKey="startEditOperator"/> + <waitForPageLoad stepKey="wait2"/> + <selectOption selector="{{PriceRuleConditionsSection.operatorByIndex('1', '1')}}" userInput="is one of" stepKey="fillOperator"/> + <waitForPageLoad stepKey="wait3"/> + <click selector="{{PriceRuleConditionsSection.ruleParamLink('1', '1', '2')}}" stepKey="startEditValue"/> + <waitForPageLoad stepKey="wait4"/> + <fillField selector="{{PriceRuleConditionsSection.valueByIndex('1', '1')}}" userInput="78613" stepKey="fillValue"/> + <waitForPageLoad stepKey="wait5"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="9.99" stepKey="fillDiscountAmount"/> + <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> + <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> + + <!-- Add the product we created to our cart --> + <amOnPage url="$$createPreReqProduct.name$$.html" stepKey="goToProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <fillField selector="{{StorefrontProductActionSection.quantity}}" userInput="1" stepKey="fillQuantity"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart"/> + <waitForPageLoad stepKey="waitForAddToCart"/> + + <!-- Should not see the discount yet because we have not filled in postcode --> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> + <waitForPageLoad stepKey="waitForCartPage"/> + <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> + <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> + + <!-- See discount if we use valid postcode --> + <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> + <fillField selector="{{CheckoutCartSummarySection.postcode}}" userInput="78613" stepKey="fillPostcode"/> + <waitForPageLoad stepKey="waitForPostcode1"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> + <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$9.99" stepKey="seeDiscountTotal"/> + + <!-- Do not see discount with other postcode --> + <fillField selector="{{CheckoutCartSummarySection.postcode}}" userInput="90210" stepKey="fillPostcode2"/> + <waitForPageLoad stepKey="waitForPostcode2"/> + <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount2"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleQuantity.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleQuantity.xml new file mode 100644 index 0000000000000..f4342b5d480b4 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleQuantity.xml @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontCartPriceRuleQuantity"> + <annotations> + <features value="SalesRule"/> + <stories value="Create cart price rule"/> + <title value="Customer should only see cart price rule discount if condition total items quantity greater than"/> + <description value="Customer should only see cart price rule discount if condition total items quantity greater than"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-236"/> + <group value="SalesRule"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="_defaultProduct" stepKey="createPreReqProduct"> + <requiredEntity createDataKey="createPreReqCategory"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <actionGroup ref="DeleteCartPriceRuleByName" stepKey="cleanUpRule"> + <argument name="ruleName" value="{{SimpleSalesRule.name}}"/> + </actionGroup> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="createPreReqProduct" stepKey="deletePreReqProduct"/> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + + <!-- Create the rule... --> + <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> + <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> + <!-- Scroll down to fix some flaky behavior... --> + <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> + <waitForElementVisible selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="waitForNewRule"/> + <click selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="clickNewRule"/> + <selectOption selector="{{PriceRuleConditionsSection.rulesDropdown}}" userInput="Total Items Quantity" stepKey="selectProductAttributes"/> + <waitForPageLoad stepKey="waitForConditions"/> + <click selector="{{PriceRuleConditionsSection.ruleParamLink('1', '1', '1')}}" stepKey="startEditOperator"/> + <selectOption selector="{{PriceRuleConditionsSection.operatorByIndex('1', '1')}}" userInput="greater than" stepKey="fillOperator"/> + <click selector="{{PriceRuleConditionsSection.ruleParamLink('1', '1', '2')}}" stepKey="startEditValue"/> + <fillField selector="{{PriceRuleConditionsSection.valueByIndex('1', '1')}}" userInput="1" stepKey="fillValue"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="1.00" stepKey="fillDiscountAmount"/> + <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> + <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> + + <!-- Add 1 product to the cart --> + <amOnPage url="$$createPreReqProduct.name$$.html" stepKey="goToProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <fillField selector="{{StorefrontProductActionSection.quantity}}" userInput="1" stepKey="fillQuantity"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart"/> + <waitForPageLoad stepKey="waitForAddToCart"/> + + <!-- Should not see the discount yet because we have only 1 item in our cart --> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> + <waitForPageLoad stepKey="waitForCartPage"/> + <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> + <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> + + <!-- Add the same product to the cart again (2 total) --> + <amOnPage url="$$createPreReqProduct.name$$.html" stepKey="goToProductPage2"/> + <waitForPageLoad stepKey="waitForProductPageLoad2"/> + <fillField selector="{{StorefrontProductActionSection.quantity}}" userInput="1" stepKey="fillQuantity2"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart2"/> + <waitForPageLoad stepKey="waitForAddToCart2"/> + + <!-- Now we should see the discount because we have more than 1 item --> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage2"/> + <waitForPageLoad stepKey="waitForCartPage2"/> + <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$246.00" stepKey="seeSubtotal2"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> + <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$1.00" stepKey="seeDiscountTotal"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleState.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleState.xml new file mode 100644 index 0000000000000..e2de2117d78e7 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleState.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontCartPriceRuleState"> + <annotations> + <features value="SalesRule"/> + <stories value="Create cart price rule"/> + <title value="Customer should only see cart price rule discount if condition shipping state/province"/> + <description value="Customer should only see cart price rule discount if condition shipping state/province"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-239"/> + <group value="SalesRule"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="_defaultProduct" stepKey="createPreReqProduct"> + <requiredEntity createDataKey="createPreReqCategory"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <actionGroup ref="DeleteCartPriceRuleByName" stepKey="cleanUpRule"> + <argument name="ruleName" value="{{SimpleSalesRule.name}}"/> + </actionGroup> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="createPreReqProduct" stepKey="deletePreReqProduct"/> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + + <!-- Create the rule... --> + <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> + <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> + <!-- Scroll down to fix some flaky behavior... --> + <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> + <waitForElementVisible selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="waitForNewRule"/> + <click selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="clickNewRule"/> + <selectOption selector="{{PriceRuleConditionsSection.rulesDropdown}}" userInput="Shipping State/Province" stepKey="selectProductAttributes"/> + <waitForPageLoad stepKey="wait1"/> + <click selector="{{PriceRuleConditionsSection.ruleParamLink('1', '1', '2')}}" stepKey="startEditValue"/> + <waitForPageLoad stepKey="wait2"/> + <selectOption selector="{{PriceRuleConditionsSection.valueByIndex('1', '1')}}" userInput="Indiana" stepKey="fillValue"/> + <waitForPageLoad stepKey="wait3"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="9.99" stepKey="fillDiscountAmount"/> + <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> + <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> + + <!-- Add the product we created to our cart --> + <amOnPage url="$$createPreReqProduct.name$$.html" stepKey="goToProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <fillField selector="{{StorefrontProductActionSection.quantity}}" userInput="1" stepKey="fillQuantity"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart"/> + <waitForPageLoad stepKey="waitForAddToCart"/> + + <!-- Should not see the discount yet because we have not filled in postcode --> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> + <waitForPageLoad stepKey="waitForCartPage"/> + <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> + <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> + + <!-- See discount if we use valid postcode --> + <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> + <selectOption selector="{{CheckoutCartSummarySection.stateProvince}}" userInput="Indiana" stepKey="fillState"/> + <waitForPageLoad stepKey="waitForPostcode1"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> + <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$9.99" stepKey="seeDiscountTotal"/> + + <!-- Do not see discount with other postcode --> + <selectOption selector="{{CheckoutCartSummarySection.stateProvince}}" userInput="Texas" stepKey="fillState2"/> + <waitForPageLoad stepKey="waitForPostcode2"/> + <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount2"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleSubtotal.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleSubtotal.xml new file mode 100644 index 0000000000000..6c49534ee43c1 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Test/StorefrontCartPriceRuleSubtotal.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontCartPriceRuleSubtotal"> + <annotations> + <features value="SalesRule"/> + <stories value="Create cart price rule"/> + <title value="Customer should only see cart price rule discount if condition subtotal equals or greater than"/> + <description value="Customer should only see cart price rule discount if condition subtotal equals or greater than"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-235"/> + <group value="SalesRule"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="_defaultProduct" stepKey="createPreReqProduct"> + <requiredEntity createDataKey="createPreReqCategory"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <actionGroup ref="DeleteCartPriceRuleByName" stepKey="cleanUpRule"> + <argument name="ruleName" value="{{SimpleSalesRule.name}}"/> + </actionGroup> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="createPreReqProduct" stepKey="deletePreReqProduct"/> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + + <!-- Create the rule... --> + <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> + <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> + <!-- Scroll down to fix some flaky behavior... --> + <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> + <click selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="clickNewRule"/> + <selectOption selector="{{PriceRuleConditionsSection.rulesDropdown}}" userInput="Subtotal" stepKey="selectProductAttributes"/> + <waitForPageLoad stepKey="waitForConditions"/> + <click selector="{{PriceRuleConditionsSection.ruleParamLink('1', '1', '1')}}" stepKey="startEditOperator"/> + <selectOption selector="{{PriceRuleConditionsSection.operatorByIndex('1', '1')}}" userInput="equals or greater than" stepKey="fillOperator"/> + <click selector="{{PriceRuleConditionsSection.ruleParamLink('1', '1', '2')}}" stepKey="startEditValue"/> + <fillField selector="{{PriceRuleConditionsSection.valueByIndex('1', '1')}}" userInput="200" stepKey="fillValue"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="0.01" stepKey="fillDiscountAmount"/> + <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> + <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> + + <!-- Add 1 product worth $123.00 to the cart --> + <amOnPage url="$$createPreReqProduct.name$$.html" stepKey="goToProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <fillField selector="{{StorefrontProductActionSection.quantity}}" userInput="1" stepKey="fillQuantity"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart"/> + <waitForPageLoad stepKey="waitForAddToCart"/> + + <!-- Should not see the discount yet because we have not exceeded $200 --> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> + <waitForPageLoad stepKey="waitForCartPage"/> + <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> + <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> + + <!-- Add the same product to the cart again ($246.00 subtotal) --> + <amOnPage url="$$createPreReqProduct.name$$.html" stepKey="goToProductPage2"/> + <waitForPageLoad stepKey="waitForProductPageLoad2"/> + <fillField selector="{{StorefrontProductActionSection.quantity}}" userInput="1" stepKey="fillQuantity2"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart2"/> + <waitForPageLoad stepKey="waitForAddToCart2"/> + + <!-- Now we should see the discount because we exceeded $200 --> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage2"/> + <waitForPageLoad stepKey="waitForCartPage2"/> + <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$246.00" stepKey="seeSubtotal2"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> + <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$0.01" stepKey="seeDiscountTotal"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AdvancedSampleTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AdvancedSampleTest.xml index 8632c6b600f35..d7a03d4f0198f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AdvancedSampleTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AdvancedSampleTest.xml @@ -11,6 +11,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdvancedSampleTest"> <annotations> + <features value="SampleTests"/> <title value=""/> <description value=""/> <severity value="CRITICAL"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AssertsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AssertsTest.xml index 359e2e94d8b76..e1e0602d6103d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AssertsTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/AssertsTest.xml @@ -10,7 +10,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AssertsTest"> <annotations> - <features value="Test Asserts"/> + <features value="SampleTests"/> <group value="skip"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateConfigurableProductByApiTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateConfigurableProductByApiTest.xml index a96f456655049..cf0ea0225a4b1 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateConfigurableProductByApiTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateConfigurableProductByApiTest.xml @@ -10,7 +10,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="CreateConfigurableProductByApiTest"> <annotations> - <features value="Create a Configurable Product By API"/> + <features value="SampleTests"/> <stories value="Create a Configurable Product By API"/> <group value="skip"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateSalesRuleByApiTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateSalesRuleByApiTest.xml index 6106cd7441195..8e9336dd6f149 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateSalesRuleByApiTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/CreateSalesRuleByApiTest.xml @@ -10,7 +10,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="CreateSalesRuleByApiTest"> <annotations> - <features value="Create a Sales Rule By API"/> + <features value="SampleTests"/> <stories value="Create a Sales Rule By API"/> <group value="skip"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/MinimumTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/MinimumTest.xml index 8edb5a9f11c92..f8702eeaf5e0c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/MinimumTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/MinimumTest.xml @@ -10,6 +10,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="MinimumTest"> <annotations> + <features value="SampleTests"/> <title value="Minimum Test"/> <description value="Minimum Test"/> <group value="example"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/PersistMultipleEntitiesTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/PersistMultipleEntitiesTest.xml index 0d2c1d24c5c04..b809ab89cba52 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/PersistMultipleEntitiesTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/PersistMultipleEntitiesTest.xml @@ -10,6 +10,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="PersistMultipleEntitiesTest"> <annotations> + <features value="SampleTests"/> <group value="skip"/> </annotations> <before> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SampleTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SampleTest.xml index 9e4a470b88950..c107debc1aa62 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SampleTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SampleTest.xml @@ -22,6 +22,7 @@ </test> <test name="AllCodeceptionMethodsTest"> <annotations> + <features value="SampleTests"/> <title value="Create all Codeception methods"/> <description value="Exercises the Generator to make sure it creates every Codeception method correctly."/> <severity value="CRITICAL"/> @@ -202,6 +203,7 @@ </test> <test name="AllVariableMethodsTest"> <annotations> + <features value="SampleTests"/> <title value="Create all Methods that support Variables."/> <description value="Exercises the Generator to make sure it creates every Method that supports a Variable."/> <severity value="CRITICAL"/> @@ -255,6 +257,7 @@ </test> <test name="AllReplacementTest"> <annotations> + <features value="SampleTests"/> <title value="Exercise reference replacement."/> <description value="Exercises {{foo}}, $foo$, and $$foo$$ replacement."/> <severity value="CRITICAL"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SetPaymentConfigurationTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SetPaymentConfigurationTest.xml index 1dcc8d2a128cd..1bc6bd1865f7c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SetPaymentConfigurationTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/SetPaymentConfigurationTest.xml @@ -10,6 +10,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="SetPaypalConfigurationTest"> <annotations> + <features value="SampleTests"/> <group value="skip"/> </annotations> <createData entity="SamplePaypalConfig" stepKey="createSamplePaypalConfig"/> @@ -17,6 +18,7 @@ </test> <test name="SetBraintreeConfigurationTest"> <annotations> + <features value="SampleTests"/> <group value="skip"/> </annotations> <createData entity="SampleBraintreeConfig" stepKey="createSampleBraintreeConfig"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/UpdateSimpleProductByApiTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/UpdateSimpleProductByApiTest.xml index 3dc313f526e90..fbf203834b45e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/UpdateSimpleProductByApiTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SampleTests/Test/UpdateSimpleProductByApiTest.xml @@ -9,7 +9,7 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="UpdateSimpleProductByApiTest"> <annotations> - <features value="Update simple product by api test."/> + <features value="SampleTests"/> <stories value="Update simple product by api test."/> <group value="skip"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateNewStoreGroupActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateNewStoreGroupActionGroup.xml index 83aa1a4735935..980e540b6b9b4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateNewStoreGroupActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateNewStoreGroupActionGroup.xml @@ -9,12 +9,17 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminCreateNewStoreGroupActionGroup"> + <arguments> + <argument name="website" type="string"/> + <argument name="storeGroupName" type="string"/> + <argument name="storeGroupCode" type="string"/> + </arguments> <amOnPage url="{{AdminSystemStoreGroupPage.url}}" stepKey="navigateToNewStoreView"/> <waitForPageLoad stepKey="waitForPageLoad1" /> <!--Create Store group --> - <selectOption selector="{{AdminNewStoreGroupSection.storeGrpWebsiteDropdown}}" userInput="Second Website" stepKey="selectWebsite" /> - <fillField selector="{{AdminNewStoreGroupSection.storeGrpNameTextField}}" userInput="Second Store" stepKey="enterStoreGroupName" /> - <fillField selector="{{AdminNewStoreGroupSection.storeGrpCodeTextField}}" userInput="second_store" stepKey="enterStoreGroupCode" /> + <selectOption selector="{{AdminNewStoreGroupSection.storeGrpWebsiteDropdown}}" userInput="{{website}}" stepKey="selectWebsite" /> + <fillField selector="{{AdminNewStoreGroupSection.storeGrpNameTextField}}" userInput="{{storeGroupName}}" stepKey="enterStoreGroupName" /> + <fillField selector="{{AdminNewStoreGroupSection.storeGrpCodeTextField}}" userInput="{{storeGroupCode}}" stepKey="enterStoreGroupCode" /> <selectOption selector="{{AdminNewStoreGroupSection.storeRootCategoryDropdown}}" userInput="Default Category" stepKey="chooseRootCategory" /> <click selector="{{AdminStoreGroupActionsSection.saveButton}}" stepKey="clickSaveStoreGroup" /> <waitForElementVisible selector="{{AdminStoresGridSection.storeGrpFilterTextField}}" stepKey="waitForStoreGridReload"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateWebsiteActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateWebsiteActionGroup.xml index c34e6c0814bb8..01d14f60bd011 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateWebsiteActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateWebsiteActionGroup.xml @@ -9,11 +9,15 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminCreateWebsiteActionGroup"> + <arguments> + <argument name="newWebsiteName" type="string"/> + <argument name="websiteCode" type="string"/> + </arguments> <amOnPage url="{{AdminSystemStoreWebsitePage.url}}" stepKey="navigateToNewWebsitePage"/> <waitForPageLoad stepKey="waitForStoresPageLoad"/> <!--Create Website--> - <fillField selector="{{AdminNewWebsiteSection.name}}" userInput="Second Website" stepKey="enterWebsiteName" /> - <fillField selector="{{AdminNewWebsiteSection.code}}" userInput="second_website" stepKey="enterWebsiteCode" /> + <fillField selector="{{AdminNewWebsiteSection.name}}" userInput="{{newWebsiteName}}" stepKey="enterWebsiteName" /> + <fillField selector="{{AdminNewWebsiteSection.code}}" userInput="{{websiteCode}}" stepKey="enterWebsiteCode" /> <click selector="{{AdminNewWebsiteActionsSection.saveWebsite}}" stepKey="clickSaveWebsite" /> <waitForElementVisible selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="waitForStoreGridToReload"/> <see userInput="You saved the website." stepKey="seeSavedMessage" /> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminDeleteWebsiteActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminDeleteWebsiteActionGroup.xml index 9b61315f0d5b8..8182a5d6dd1e3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminDeleteWebsiteActionGroup.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminDeleteWebsiteActionGroup.xml @@ -8,11 +8,14 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminDeleteWebsiteActionGroup"> + <arguments> + <argument name="websiteName" type="string"/> + </arguments> <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="amOnAdminSystemStorePage"/> <click selector="{{AdminStoresGridSection.resetButton}}" stepKey="resetSearchFilter"/> - <fillField userInput="Second Website" selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="fillSearchWebsiteField"/> + <fillField userInput="{{websiteName}}" selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="fillSearchWebsiteField"/> <click selector="{{AdminStoresGridSection.searchButton}}" stepKey="clickSearchButton"/> - <see userInput="Second Website" selector="{{AdminStoresGridSection.websiteNameInFirstRow}}" stepKey="verifyThatCorrectWebsiteFound"/> + <see userInput="{{websiteName}}" selector="{{AdminStoresGridSection.websiteNameInFirstRow}}" stepKey="verifyThatCorrectWebsiteFound"/> <click selector="{{AdminStoresGridSection.websiteNameInFirstRow}}" stepKey="clickEditExistingStoreRow"/> <waitForPageLoad stepKey="waitForStoreToLoad"/> <click selector="{{AdminStoresMainActionsSection.deleteButton}}" stepKey="clickDeleteWebsiteButtonOnEditWebsitePage"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreGroupTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreGroupTest.xml index 58867227d08da..1d3cad0cd4f27 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreGroupTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreGroupTest.xml @@ -9,10 +9,10 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateStoreGroupTest"> <annotations> - <features value="Create a store group in admin"/> + <features value="Store"/> <stories value="Create a store group in admin"/> - <title value="Create a store group in admin"/> - <description value="Create a store group in admin"/> + <title value="Admin should be able to create a store group"/> + <description value="Admin should be able to create a store group"/> <group value="store"/> </annotations> <before> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreViewTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreViewTest.xml index 6fcaf45a0acbc..9d6a71f009beb 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreViewTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreViewTest.xml @@ -9,8 +9,10 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminCreateStoreViewTest"> <annotations> - <title value="Create a store view in admin"/> - <description value="Create a store view in admin"/> + <features value="Store"/> + <stories value="Create a store view in admin"/> + <title value="Admin should be able to create a store view"/> + <description value="Admin should be able to create a store view"/> <group value="storeView"/> </annotations> <before> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/ActionGroup/AdminTaxActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/ActionGroup/AdminTaxActionGroup.xml new file mode 100644 index 0000000000000..946402d080e99 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/ActionGroup/AdminTaxActionGroup.xml @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <!-- Change the tax configuration to display in cart and checkout flow --> + <actionGroup name="editTaxConfigurationByUI"> + <!-- navigate to the tax configuration page --> + <amOnPage url="{{AdminTaxConfigurationPage.url}}" stepKey="goToAdminTaxPage"/> + <waitForPageLoad stepKey="waitForTaxConfigLoad"/> + + <!-- change the default state to California --> + <conditionalClick stepKey="clickCalculationSettings" selector="{{AdminConfigureTaxSection.defaultDestination}}" dependentSelector="{{AdminConfigureTaxSection.systemValueDefaultState}}" visible="false" /> + <uncheckOption stepKey="clickDefaultState" selector="{{AdminConfigureTaxSection.systemValueDefaultState}}"/> + <selectOption stepKey="selectDefaultState" selector="{{AdminConfigureTaxSection.dropdownDefaultState}}" userInput="California"/> + <fillField stepKey="fillDefaultPostCode" selector="{{AdminConfigureTaxSection.defaultPostCode}}" userInput="*"/> + + <!-- change the options for shopping cart display to show tax --> + <conditionalClick stepKey="clickShoppingCartDisplaySettings" selector="{{AdminConfigureTaxSection.shoppingCartDisplay}}" dependentSelector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalCart}}" visible="false"/> + <uncheckOption stepKey="clickTaxTotalCart" selector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalCart}}"/> + <selectOption stepKey="selectTaxTotalCart" selector="{{AdminConfigureTaxSection.dropdownIncludeTaxTotalCart}}" userInput="Yes"/> + <uncheckOption stepKey="clickDisplayTaxSummaryCart" selector="{{AdminConfigureTaxSection.systemValueDisplayTaxSummaryCart}}"/> + <selectOption stepKey="selectDisplayTaxSummaryCart" selector="{{AdminConfigureTaxSection.dropdownDisplayTaxSummaryCart}}" userInput="Yes"/> + <uncheckOption stepKey="clickDisplayZeroTaxCart" selector="{{AdminConfigureTaxSection.systemValueDisplayZeroTaxCart}}"/> + <selectOption stepKey="selectDisplayZeroTaxCart" selector="{{AdminConfigureTaxSection.dropdownDisplayZeroTaxCart}}" userInput="Yes"/> + + <!-- change the options for orders, invoices, credit memos display to show tax --> + <conditionalClick stepKey="clickOrdersInvoicesCreditSales" selector="{{AdminConfigureTaxSection.ordersInvoicesCreditSales}}" dependentSelector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalSales}}" visible="false"/> + <uncheckOption stepKey="clickTaxTotalSales" selector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalSales}}"/> + <selectOption stepKey="selectTaxTotalSales" selector="{{AdminConfigureTaxSection.dropdownIncludeTaxTotalSales}}" userInput="Yes"/> + <uncheckOption stepKey="clickDisplayTaxSummarySales" selector="{{AdminConfigureTaxSection.systemValueDisplayTaxSummarySales}}"/> + <selectOption stepKey="selectDisplayTaxSummarySales" selector="{{AdminConfigureTaxSection.dropdownDisplayTaxSummarySales}}" userInput="Yes"/> + <uncheckOption stepKey="clickDisplayZeroTaxSales" selector="{{AdminConfigureTaxSection.systemValueDisplayZeroTaxSales}}"/> + <selectOption stepKey="selectDisplayZeroTaxSales" selector="{{AdminConfigureTaxSection.dropdownDisplayZeroTaxSales}}" userInput="Yes"/> + + <!-- Save the settings --> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click stepKey="saveTaxOptions" selector="{{AdminCategoryMainActionsSection.SaveButton}}"/> + <waitForPageLoad stepKey="waitForTaxSaved"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the configuration."/> + </actionGroup> + + <actionGroup name="changeToDefaultTaxConfigurationUI"> + <!-- navigate to the tax configuration page --> + <amOnPage url="{{AdminTaxConfigurationPage.url}}" stepKey="goToAdminTaxPage"/> + <waitForPageLoad stepKey="waitForTaxConfigLoad"/> + + <!-- change the default state to none --> + <conditionalClick stepKey="clickCalculationSettings" selector="{{AdminConfigureTaxSection.defaultDestination}}" dependentSelector="{{AdminConfigureTaxSection.systemValueDefaultState}}" visible="false" /> + <checkOption stepKey="clickDefaultState" selector="{{AdminConfigureTaxSection.systemValueDefaultState}}"/> + <selectOption stepKey="selectDefaultState" selector="{{AdminConfigureTaxSection.dropdownDefaultState}}" userInput="California"/> + <fillField stepKey="fillDefaultPostCode" selector="{{AdminConfigureTaxSection.defaultPostCode}}" userInput=""/> + + <!-- change the options for shopping cart display to not show tax --> + <conditionalClick stepKey="clickShoppingCartDisplaySettings" selector="{{AdminConfigureTaxSection.shoppingCartDisplay}}" dependentSelector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalCart}}" visible="false"/> + <checkOption stepKey="clickTaxTotalCart" selector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalCart}}"/> + <selectOption stepKey="selectTaxTotalCart" selector="{{AdminConfigureTaxSection.dropdownIncludeTaxTotalCart}}" userInput="Yes"/> + <checkOption stepKey="clickDisplayTaxSummaryCart" selector="{{AdminConfigureTaxSection.systemValueDisplayTaxSummaryCart}}"/> + <selectOption stepKey="selectDisplayTaxSummaryCart" selector="{{AdminConfigureTaxSection.dropdownDisplayTaxSummaryCart}}" userInput="Yes"/> + <checkOption stepKey="clickDisplayZeroTaxCart" selector="{{AdminConfigureTaxSection.systemValueDisplayZeroTaxCart}}"/> + <selectOption stepKey="selectDisplayZeroTaxCart" selector="{{AdminConfigureTaxSection.dropdownDisplayZeroTaxCart}}" userInput="Yes"/> + + <!-- change the options for orders, invoices, credit memos display to not show tax --> + <conditionalClick stepKey="clickOrdersInvoicesCreditSales" selector="{{AdminConfigureTaxSection.ordersInvoicesCreditSales}}" dependentSelector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalSales}}" visible="false"/> + <checkOption stepKey="clickTaxTotalSales" selector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalSales}}"/> + <selectOption stepKey="selectTaxTotalSales" selector="{{AdminConfigureTaxSection.dropdownIncludeTaxTotalSales}}" userInput="Yes"/> + <checkOption stepKey="clickDisplayTaxSummarySales" selector="{{AdminConfigureTaxSection.systemValueDisplayTaxSummarySales}}"/> + <selectOption stepKey="selectDisplayTaxSummarySales" selector="{{AdminConfigureTaxSection.dropdownDisplayTaxSummarySales}}" userInput="Yes"/> + <checkOption stepKey="clickDisplayZeroTaxSales" selector="{{AdminConfigureTaxSection.systemValueDisplayZeroTaxSales}}"/> + <selectOption stepKey="selectDisplayZeroTaxSales" selector="{{AdminConfigureTaxSection.dropdownDisplayZeroTaxSales}}" userInput="Yes"/> + + <!-- Save the settings --> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click stepKey="saveTaxOptions" selector="{{AdminCategoryMainActionsSection.SaveButton}}"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the configuration."/> + </actionGroup> + + <!-- Action group to add a tax rate when on a tax rule configuration page --> + <!-- Must already be on a tax rule configuration page or a new tax rule page --> + <actionGroup name="addNewTaxRateNoZip"> + <arguments> + <argument name="taxCode"/> + </arguments> + + <!-- Go to the tax rate page --> + <click stepKey="addNewTaxRate" selector="{{AdminTaxRulesSection.addNewTaxRate}}"/> + + <!-- Fill out a new tax rate --> + <fillField stepKey="fillTaxIdentifier" selector="{{AdminTaxRulesSection.taxIdentifier}}" userInput="{{taxCode.state}}-{{taxCode.rate}}"/> + <fillField stepKey="fillZipCode" selector="{{AdminTaxRulesSection.zipCode}}" userInput="{{taxCode.zip}}"/> + <selectOption stepKey="selectState" selector="{{AdminTaxRulesSection.state}}" userInput="{{taxCode.state}}"/> + <selectOption stepKey="selectCountry" selector="{{AdminTaxRulesSection.country}}" userInput="{{taxCode.country}}"/> + <fillField stepKey="fillRate" selector="{{AdminTaxRulesSection.rate}}" userInput="{{taxCode.rate}}"/> + + <!-- Save the tax rate --> + <click stepKey="saveTaxRate" selector="{{AdminTaxRulesSection.save}}"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Data/TaxCodeData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Data/TaxCodeData.xml new file mode 100644 index 0000000000000..ac603751ddc78 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Data/TaxCodeData.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="SimpleTaxNY" type="tax"> + <data key="state">New York</data> + <data key="country">United States</data> + <data key="zip">*</data> + <data key="rate">8.375</data> + </entity> + <entity name="SimpleTaxCA" type="tax"> + <data key="state">California</data> + <data key="country">United States</data> + <data key="zip">*</data> + <data key="rate">8.25</data> + </entity> + <entity name="SimpleTaxSwiss" type="tax"> + <data key="state">Aargau</data> + <data key="country">Switzerland</data> + <data key="zip">*</data> + <data key="rate">0</data> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminNewTaxRulePage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminNewTaxRulePage.xml new file mode 100644 index 0000000000000..74a0347b33c7c --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminNewTaxRulePage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="AdminNewTaxRulePage" url="tax/rule/new/" module="Magento_Tax" area="admin"> + <section name="AdminTaxRulesSection"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminTaxConfigurationPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminTaxConfigurationPage.xml new file mode 100644 index 0000000000000..b91344000ff50 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminTaxConfigurationPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="AdminTaxConfigurationPage" url="admin/system_config/edit/section/tax/" area="admin" module="Magento_Tax"> + <section name="AdminConfigureTaxSection"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminTaxRateGridPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminTaxRateGridPage.xml new file mode 100644 index 0000000000000..a6624f6588d97 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminTaxRateGridPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="AdminTaxRateGridPage" url="tax/rate/" area="admin" module="Magento_Tax"> + <section name="AdminSecondaryGridSection"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminTaxRuleGridPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminTaxRuleGridPage.xml new file mode 100644 index 0000000000000..e673da4a761f0 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Page/AdminTaxRuleGridPage.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="AdminTaxRuleGridPage" url="tax/rule" area="admin" module="Magento_Tax"> + <section name="AdminSecondaryGridSection"/> + <section name="AdminGridMainControls"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Section/AdminConfigureTaxSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Section/AdminConfigureTaxSection.xml new file mode 100644 index 0000000000000..8ae17928d3bbd --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Section/AdminConfigureTaxSection.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminConfigureTaxSection"> + <!-- on page /admin/admin/system_config/edit/section/tax/ --> + <element name="taxClasses" type="block" selector="#tax_classes-head" timeout="30"/> + <element name="calculationSettings" type="block" selector="#tax_calculation-head:not(.open)" timeout="30"/> + + <element name="defaultDestination" type="block" selector="#tax_defaults-head" timeout="30"/> + <element name="systemValueDefaultState" type="checkbox" selector="#row_tax_defaults_region input[type='checkbox']"/> + <element name="dropdownDefaultState" type="select" selector="#row_tax_defaults_region select"/> + <element name="defaultPostCode" type="input" selector="#tax_defaults_postcode"/> + + <element name="priceDisplaySettings" type="block" selector="#tax_display-head:not(.open)" timeout="30"/> + + <element name="shoppingCartDisplay" type="block" selector="#tax_cart_display-head" timeout="30"/> + <element name="systemValueIncludeTaxTotalCart" type="checkbox" selector="#row_tax_cart_display_grandtotal input[type='checkbox']"/> + <element name="dropdownIncludeTaxTotalCart" type="checkbox" selector="#row_tax_cart_display_grandtotal select"/> + <element name="systemValueDisplayTaxSummaryCart" type="checkbox" selector="#row_tax_cart_display_full_summary input[type='checkbox']"/> + <element name="dropdownDisplayTaxSummaryCart" type="checkbox" selector="#row_tax_cart_display_full_summary select"/> + <element name="systemValueDisplayZeroTaxCart" type="checkbox" selector="#row_tax_cart_display_zero_tax input[type='checkbox']"/> + <element name="dropdownDisplayZeroTaxCart" type="checkbox" selector="#row_tax_cart_display_zero_tax select"/> + + <element name="ordersInvoicesCreditSales" type="block" selector="#tax_sales_display-head" timeout="30"/> + <element name="systemValueIncludeTaxTotalSales" type="checkbox" selector="#row_tax_sales_display_grandtotal input[type='checkbox']"/> + <element name="dropdownIncludeTaxTotalSales" type="checkbox" selector="#row_tax_sales_display_grandtotal select"/> + <element name="systemValueDisplayTaxSummarySales" type="checkbox" selector="#row_tax_sales_display_full_summary input[type='checkbox']"/> + <element name="dropdownDisplayTaxSummarySales" type="checkbox" selector="#row_tax_sales_display_full_summary select"/> + <element name="systemValueDisplayZeroTaxSales" type="checkbox" selector="#row_tax_sales_display_zero_tax input[type='checkbox']"/> + <element name="dropdownDisplayZeroTaxSales" type="checkbox" selector="#row_tax_sales_display_zero_tax select"/> + + <element name="priceDisplaySettings" type="block" selector="#tax_weee-head" timeout="30"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Section/AdminTaxRulesSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Section/AdminTaxRulesSection.xml new file mode 100644 index 0000000000000..df3a56a36bc4a --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Section/AdminTaxRulesSection.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminTaxRulesSection"> + <!-- on page /admin/tax/rule/new/ --> + <element name="ruleName" type="input" selector="#anchor-content #code"/> + <element name="addNewTaxRate" type="block" selector="//*[text()='Add New Tax Rate']" timeout="30"/> + <element name="taxIdentifier" type="input" selector="aside #code"/> + <element name="zipIsRange" type="checkbox" selector="#zip_is_range"/> + <element name="zipCode" type="input" selector="#tax_postcode"/> + <element name="state" type="select" selector="#tax_region_id"/> + <element name="country" type="select" selector="#tax_country_id"/> + <element name="rate" type="input" selector="#rate"/> + <element name="save" type="button" selector=".action-save" timeout="30"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Test/StorefrontTaxQuoteCartTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Test/StorefrontTaxQuoteCartTest.xml new file mode 100644 index 0000000000000..2607775ce7f36 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Test/StorefrontTaxQuoteCartTest.xml @@ -0,0 +1,458 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontTaxQuoteCartLoggedInSimple"> + <annotations> + <features value="Tax"/> + <stories value="Tax Calculation in Shopping Cart"/> + <title value="Tax for Simple Product Quote should be recalculated in Shopping Cart for Logged in Customer with Default Address"/> + <description value="Tax for Simple Product Quote should be recalculated in Shopping Cart for Logged in Customer with Default Address"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-295"/> + <group value="Tax"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + + <!-- Fill in rules to display tax in the cart --> + <actionGroup ref="editTaxConfigurationByUI" stepKey="fillDefaultTaxForms"/> + + <!-- Go to tax rule page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulePage"/> + <waitForPageLoad stepKey="waitForTaxRatePage"/> + <click stepKey="addNewTaxRate" selector="{{AdminGridMainControls.add}}"/> + <fillField stepKey="fillRuleName" selector="{{AdminTaxRulesSection.ruleName}}" userInput="SampleRule"/> + + <!-- Add NY and CA tax rules --> + <actionGroup ref="addNewTaxRateNoZip" stepKey="addNYTaxRate"> + <argument name="taxCode" value="SimpleTaxNY"/> + </actionGroup> + + <actionGroup ref="addNewTaxRateNoZip" stepKey="addCATaxRate"> + <argument name="taxCode" value="SimpleTaxCA"/> + </actionGroup> + + <click stepKey="clickSave" selector="{{AdminStoresMainActionsSection.saveButton}}"/> + + <!-- Fill out form for a new user with address --> + <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> + <argument name="Customer" value="Simple_US_Customer_NY"/> + </actionGroup> + + <actionGroup ref="EnterCustomerAddressInfo" stepKey="enterAddressInfo"> + <argument name="Address" value="US_Address_NY"/> + </actionGroup> + </before> + <after> + <!-- Go to the tax rule page and delete the row we created--> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulesPage"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteRule"> + <argument name="name" value="SampleRule"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Go to the tax rate page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRatesPage"/> + <waitForPageLoad stepKey="waitForRatesPage"/> + + <!-- Delete the two tax rates that were created --> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteNYRate"> + <argument name="name" value="{{SimpleTaxNY.state}}-{{SimpleTaxNY.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteCARate"> + <argument name="name" value="{{SimpleTaxCA.state}}-{{SimpleTaxCA.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Ensure tax wont be shown in the cart --> + <actionGroup ref="changeToDefaultTaxConfigurationUI" stepKey="changeToDefaultTaxConfiguration"/> + + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + </after> + + <!-- Go to the created product page and add it to the cart --> + <amOnPage url="$$simpleProduct1.sku$$.html" stepKey="goToSimpleProductPage"/> + <waitForPageLoad stepKey="waitForSimpleProductPage"/> + <click stepKey="addSimpleProductToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> + <waitForPageLoad stepKey="waitForProductAdded"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> + + <!-- Assert that taxes are applied correctly for NY --> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> + <waitForPageLoad stepKey="waitForCart"/> + + <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.30"/> + <click stepKey="expandTax" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxNY.rate}}%)"/> + <see stepKey="seeTotalIncl" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$138.30"/> + <see stepKey="seeTotalExcl" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$128.00"/> + + <!-- Change the address --> + <actionGroup ref="changeSummaryQuoteAddress" stepKey="changeAddress"> + <argument name="taxCode" value="SimpleTaxSwiss"/> + </actionGroup> + + <!-- Assert that taxes are applied correctly for Switzerland --> + <see stepKey="seeTax2" selector="{{CheckoutPaymentSection.tax}}" userInput="$0.00"/> + <see stepKey="seeTotalIncl2" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$128.00"/> + <see stepKey="seeTotalExcl2" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$128.00"/> + + <!-- Change the address --> + <actionGroup ref="changeSummaryQuoteAddress" stepKey="changeAddress2"> + <argument name="taxCode" value="SimpleTaxCA"/> + </actionGroup> + + <!-- Assert that taxes are applied correctly for CA --> + <see stepKey="seeTax3" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.15"/> + <click stepKey="expandTax2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent2" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxCA.rate}}%)"/> + <see stepKey="seeTotalIncl3" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$138.15"/> + <see stepKey="seeTotalExcl3" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$128.00"/> + </test> + + + <test name="StorefrontTaxQuoteCartLoggedInVirtual"> + <annotations> + <features value="Tax"/> + <stories value="Tax Calculation in Shopping Cart"/> + <title value="Tax for Virtual Product Quote should be recalculated in Shopping Cart for Logged in Customer with Default Address"/> + <description value="Tax for Virtual Product Quote should be recalculated in Shopping Cart for Logged in Customer with Default Address"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-296"/> + <group value="Tax"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="VirtualProduct" stepKey="virtualProduct1"/> + + <!-- Fill in rules to display tax in the cart --> + <actionGroup ref="editTaxConfigurationByUI" stepKey="fillDefaultTaxForms"/> + + <!-- Go to tax rule page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulePage"/> + <waitForPageLoad stepKey="waitForTaxRatePage"/> + <click stepKey="addNewTaxRate" selector="{{AdminGridMainControls.add}}"/> + <fillField stepKey="fillRuleName" selector="{{AdminTaxRulesSection.ruleName}}" userInput="SampleRule"/> + + <!-- Add NY and CA tax rules --> + <actionGroup ref="addNewTaxRateNoZip" stepKey="addNYTaxRate"> + <argument name="taxCode" value="SimpleTaxNY"/> + </actionGroup> + + <actionGroup ref="addNewTaxRateNoZip" stepKey="addCATaxRate"> + <argument name="taxCode" value="SimpleTaxCA"/> + </actionGroup> + + <click stepKey="clickSave" selector="{{AdminStoresMainActionsSection.saveButton}}"/> + + <!-- Fill out form for a new user with address --> + <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> + <argument name="Customer" value="Simple_US_Customer_NY"/> + </actionGroup> + + <actionGroup ref="EnterCustomerAddressInfo" stepKey="enterAddressInfo"> + <argument name="Address" value="US_Address_NY"/> + </actionGroup> + </before> + <after> + <!-- Go to the tax rule page and delete the row we created--> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulesPage"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteRule"> + <argument name="name" value="SampleRule"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Go to the tax rate page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRatesPage"/> + <waitForPageLoad stepKey="waitForRatesPage"/> + + <!-- Delete the two tax rates that were created --> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteNYRate"> + <argument name="name" value="{{SimpleTaxNY.state}}-{{SimpleTaxNY.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteCARate"> + <argument name="name" value="{{SimpleTaxCA.state}}-{{SimpleTaxCA.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Ensure tax wont be shown in the cart --> + <actionGroup ref="changeToDefaultTaxConfigurationUI" stepKey="changeToDefaultTaxConfiguration"/> + + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="virtualProduct1" stepKey="deleteVirtualProduct1"/> + </after> + + <!-- Go to the created product page and add it to the cart --> + <amOnPage url="$$virtualProduct1.sku$$.html" stepKey="goToVirtualProductPage"/> + <waitForPageLoad stepKey="waitForVirtualProductPage"/> + <click stepKey="addVirtualProductToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> + <waitForPageLoad stepKey="waitForProductAdded"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> + + <!-- Assert that taxes are applied correctly for NY --> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> + <waitForPageLoad stepKey="waitForCart"/> + + <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$8.37"/> + <click stepKey="expandTax" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxNY.rate}}%)"/> + <see stepKey="seeTotalIncl" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$108.36"/> + <see stepKey="seeTotalExcl" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$$virtualProduct1.price$$"/> + + <!-- Change the address --> + <actionGroup ref="changeSummaryQuoteAddress" stepKey="changeAddress"> + <argument name="taxCode" value="SimpleTaxSwiss"/> + </actionGroup> + + <!-- Assert that taxes are applied correctly for Switzerland --> + <see stepKey="seeTax2" selector="{{CheckoutPaymentSection.tax}}" userInput="$0.00"/> + <see stepKey="seeTotalIncl2" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$$$virtualProduct1.price$$"/> + <see stepKey="seeTotalExcl2" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$$$virtualProduct1.price$$"/> + + <!-- Change the address --> + <actionGroup ref="changeSummaryQuoteAddress" stepKey="changeAddress2"> + <argument name="taxCode" value="SimpleTaxCA"/> + </actionGroup> + + <!-- Assert that taxes are applied correctly for CA --> + <see stepKey="seeTax3" selector="{{CheckoutPaymentSection.tax}}" userInput="$8.25"/> + <click stepKey="expandTax2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent2" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxCA.rate}}%)"/> + <see stepKey="seeTotalIncl3" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$108.24"/> + <see stepKey="seeTotalExcl3" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$$virtualProduct1.price$$"/> + </test> + + <test name="StorefrontTaxQuoteCartGuestSimple"> + <annotations> + <features value="Tax"/> + <stories value="Tax Calculation in Shopping Cart"/> + <title value="Tax for Simple Product Quote should be recalculated in Shopping Cart for Guest Customer"/> + <description value="Tax for Simple Product Quote should be recalculated in Shopping Cart for Guest Customer#anch"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-297"/> + <group value="Tax"/> + <group value="skip"/> + <!-- skipped due to MAGETWO-90539 --> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + + <!-- Fill in rules to display tax in the cart --> + <actionGroup ref="editTaxConfigurationByUI" stepKey="fillDefaultTaxForms"/> + + <!-- Go to tax rule page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulePage"/> + <waitForPageLoad stepKey="waitForTaxRatePage"/> + <click stepKey="addNewTaxRate" selector="{{AdminGridMainControls.add}}"/> + <fillField stepKey="fillRuleName" selector="{{AdminTaxRulesSection.ruleName}}" userInput="SampleRule"/> + + <!-- Add NY and CA tax rules --> + <actionGroup ref="addNewTaxRateNoZip" stepKey="addNYTaxRate"> + <argument name="taxCode" value="SimpleTaxNY"/> + </actionGroup> + + <actionGroup ref="addNewTaxRateNoZip" stepKey="addCATaxRate"> + <argument name="taxCode" value="SimpleTaxCA"/> + </actionGroup> + + <click stepKey="clickSave" selector="{{AdminStoresMainActionsSection.saveButton}}"/> + </before> + <after> + <!-- Go to the tax rule page and delete the row we created--> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulesPage"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteRule"> + <argument name="name" value="SampleRule"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Go to the tax rate page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRatesPage"/> + <waitForPageLoad stepKey="waitForRatesPage"/> + + <!-- Delete the two tax rates that were created --> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteNYRate"> + <argument name="name" value="{{SimpleTaxNY.state}}-{{SimpleTaxNY.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteCARate"> + <argument name="name" value="{{SimpleTaxCA.state}}-{{SimpleTaxCA.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Ensure tax wont be shown in the cart --> + <actionGroup ref="changeToDefaultTaxConfigurationUI" stepKey="changeToDefaultTaxConfiguration"/> + + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + </after> + + <!-- Go to the created product page and add it to the cart --> + <amOnPage url="$$simpleProduct1.sku$$.html" stepKey="goToSimpleProductPage"/> + <waitForPageLoad stepKey="waitForSimpleProductPage"/> + <click stepKey="addSimpleProductToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> + <waitForPageLoad stepKey="waitForProductAdded"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> + + <!-- Assert that taxes are applied correctly for CA --> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> + <waitForPageLoad stepKey="waitForCart"/> + + <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax3" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.15"/> + <click stepKey="expandTax2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent2" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxCA.rate}}%)"/> + <see stepKey="seeTotalIncl3" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$138.15"/> + <see stepKey="seeTotalExcl3" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$128.00"/> + + <!-- Change the address --> + <actionGroup ref="changeSummaryQuoteAddress" stepKey="changeAddress"> + <argument name="taxCode" value="SimpleTaxSwiss"/> + </actionGroup> + + <!-- Assert that taxes are applied correctly for Switzerland --> + <see stepKey="seeTax2" selector="{{CheckoutPaymentSection.tax}}" userInput="$0.00"/> + <see stepKey="seeTotalIncl2" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$128.00"/> + <see stepKey="seeTotalExcl2" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$128.00"/> + + <!-- Change the address --> + <actionGroup ref="changeSummaryQuoteAddress" stepKey="changeAddress2"> + <argument name="taxCode" value="SimpleTaxNY"/> + </actionGroup> + + <!-- Assert that taxes are applied correctly for NY --> + <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.30"/> + <click stepKey="expandTax" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxNY.rate}}%)"/> + <see stepKey="seeTotalIncl" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$138.30"/> + <see stepKey="seeTotalExcl" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$128.00"/> + </test> + + <test name="StorefrontTaxQuoteCartGuestVirtual"> + <annotations> + <features value="Tax"/> + <stories value="Tax Calculation in Shopping Cart"/> + <title value="Tax for Virtual Product Quote should be recalculated in Shopping Cart for Guest Customer"/> + <description value="Tax for Virtual Product Quote should be recalculated in Shopping Cart for Guest Customer"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-298"/> + <group value="Tax"/> + <group value="skip"/> + <!-- Skipped due to MAGETWO-90539 --> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="VirtualProduct" stepKey="virtualProduct1"/> + + <!-- Fill in rules to display tax in the cart --> + <actionGroup ref="editTaxConfigurationByUI" stepKey="fillDefaultTaxForms"/> + + <!-- Go to tax rule page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulePage"/> + <waitForPageLoad stepKey="waitForTaxRatePage"/> + <click stepKey="addNewTaxRate" selector="{{AdminGridMainControls.add}}"/> + <fillField stepKey="fillRuleName" selector="{{AdminTaxRulesSection.ruleName}}" userInput="SampleRule"/> + + <!-- Add NY and CA tax rules --> + <actionGroup ref="addNewTaxRateNoZip" stepKey="addNYTaxRate"> + <argument name="taxCode" value="SimpleTaxNY"/> + </actionGroup> + + <actionGroup ref="addNewTaxRateNoZip" stepKey="addCATaxRate"> + <argument name="taxCode" value="SimpleTaxCA"/> + </actionGroup> + + <click stepKey="clickSave" selector="{{AdminStoresMainActionsSection.saveButton}}"/> + </before> + <after> + <!-- Go to the tax rule page and delete the row we created--> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulesPage"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteRule"> + <argument name="name" value="SampleRule"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Go to the tax rate page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRatesPage"/> + <waitForPageLoad stepKey="waitForRatesPage"/> + + <!-- Delete the two tax rates that were created --> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteNYRate"> + <argument name="name" value="{{SimpleTaxNY.state}}-{{SimpleTaxNY.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteCARate"> + <argument name="name" value="{{SimpleTaxCA.state}}-{{SimpleTaxCA.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Ensure tax wont be shown in the cart --> + <actionGroup ref="changeToDefaultTaxConfigurationUI" stepKey="changeToDefaultTaxConfiguration"/> + + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="virtualProduct1" stepKey="deleteVirtualProduct1"/> + </after> + + <!-- Go to the created product page and add it to the cart --> + <amOnPage url="$$virtualProduct1.sku$$.html" stepKey="goToVirtualProductPage"/> + <waitForPageLoad stepKey="waitForVirtualProductPage"/> + <click stepKey="addVirtualProductToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> + <waitForPageLoad stepKey="waitForProductAdded"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> + + <!-- Assert that taxes are applied correctly for NY --> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> + <waitForPageLoad stepKey="waitForCart"/> + + <!-- Assert that taxes are applied correctly for CA --> + <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax3" selector="{{CheckoutPaymentSection.tax}}" userInput="$8.25"/> + <click stepKey="expandTax2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent2" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxCA.rate}}%)"/> + <see stepKey="seeTotalIncl3" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$108.24"/> + <see stepKey="seeTotalExcl3" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$$virtualProduct1.price$$"/> + + <!-- Change the address --> + <actionGroup ref="changeSummaryQuoteAddress" stepKey="changeAddress"> + <argument name="taxCode" value="SimpleTaxSwiss"/> + </actionGroup> + + <!-- Assert that taxes are applied correctly for Switzerland --> + <see stepKey="seeTax2" selector="{{CheckoutPaymentSection.tax}}" userInput="$0.00"/> + <see stepKey="seeTotalIncl2" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$$$virtualProduct1.price$$"/> + <see stepKey="seeTotalExcl2" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$$$virtualProduct1.price$$"/> + + <!-- Change the address --> + <actionGroup ref="changeSummaryQuoteAddress" stepKey="changeAddress2"> + <argument name="taxCode" value="SimpleTaxNY"/> + </actionGroup> + + <!-- Assert that taxes are applied correctly for NY --> + <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$8.37"/> + <click stepKey="expandTax" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxNY.rate}}%)"/> + <see stepKey="seeTotalIncl" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$108.36"/> + <see stepKey="seeTotalExcl" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$$virtualProduct1.price$$"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Test/StorefrontTaxQuoteCheckoutTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Test/StorefrontTaxQuoteCheckoutTest.xml new file mode 100644 index 0000000000000..6b60201a00709 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/Test/StorefrontTaxQuoteCheckoutTest.xml @@ -0,0 +1,458 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontTaxQuoteCheckoutGuestVirtual"> + <annotations> + <features value="Tax"/> + <stories value="Tax Calculation in One Page Checkout"/> + <title value="Tax for Virtual Product Quote should be recalculated according to inputted data on Checkout flow for Guest Customer"/> + <description value="Tax for Virtual Product Quote should be recalculated according to inputted data on Checkout flow for Guest Customer"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-255"/> + <group value="Tax"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="VirtualProduct" stepKey="virtualProduct1"/> + + <!-- Fill in rules to display tax in the cart --> + <actionGroup ref="editTaxConfigurationByUI" stepKey="fillDefaultTaxForms"/> + + <!-- Go to tax rule page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulePage"/> + <waitForPageLoad stepKey="waitForTaxRatePage"/> + <click stepKey="addNewTaxRate" selector="{{AdminGridMainControls.add}}"/> + <fillField stepKey="fillRuleName" selector="{{AdminTaxRulesSection.ruleName}}" userInput="SampleRule"/> + + <!-- Add NY and CA tax rules --> + <actionGroup ref="addNewTaxRateNoZip" stepKey="addNYTaxRate"> + <argument name="taxCode" value="SimpleTaxNY"/> + </actionGroup> + + <actionGroup ref="addNewTaxRateNoZip" stepKey="addCATaxRate"> + <argument name="taxCode" value="SimpleTaxCA"/> + </actionGroup> + + <click stepKey="clickSave" selector="{{AdminStoresMainActionsSection.saveButton}}"/> + </before> + <after> + <!-- Go to the tax rule page and delete the row we created--> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulesPage"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteRule"> + <argument name="name" value="SampleRule"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Go to the tax rate page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRatesPage"/> + <waitForPageLoad stepKey="waitForRatesPage"/> + + <!-- Delete the two tax rates that were created --> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteNYRate"> + <argument name="name" value="{{SimpleTaxNY.state}}-{{SimpleTaxNY.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteCARate"> + <argument name="name" value="{{SimpleTaxCA.state}}-{{SimpleTaxCA.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Ensure tax wont be shown in the cart --> + <actionGroup ref="changeToDefaultTaxConfigurationUI" stepKey="changeToDefaultTaxConfiguration"/> + + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="virtualProduct1" stepKey="deleteVirtualProduct1"/> + </after> + + <!-- Go to the created product page and add it to the cart --> + <amOnPage url="$$virtualProduct1.sku$$.html" stepKey="goToVirtualProductPage"/> + <waitForPageLoad stepKey="waitForVirtualProductPage"/> + <click stepKey="addVirtualProductToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> + <waitForPageLoad stepKey="waitForProductAdded"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> + + <!-- Assert that taxes are applied correctly for CA --> + <amOnPage url="{{CheckoutPage.url}}" stepKey="goToCheckout"/> + <waitForPageLoad stepKey="waitForShippingSection"/> + + <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax2" selector="{{CheckoutPaymentSection.tax}}" userInput="$8.25"/> + <click stepKey="expandTax2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent2" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxCA.rate}}%)"/> + <see stepKey="seeTotalIncl2" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$108.24"/> + <see stepKey="seeTotalExcl2" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$$virtualProduct1.price$$"/> + + <!-- Change the address --> + <actionGroup ref="GuestCheckoutFillNewBillingAddressActionGroup" stepKey="changeAddress"> + <argument name="customerVar" value="Simple_US_Customer_NY"/> + <argument name="customerAddressVar" value="US_Address_NY"/> + </actionGroup> + <click stepKey="saveAddress" selector="{{CheckoutShippingSection.updateAddress}}"/> + + <waitForPageLoad stepKey="waitForAddressSaved"/> + <see stepKey="seeEditButton" selector="{{CheckoutShippingSection.editAddressButton}}" userInput="Edit"/> + <see stepKey="seeAddress2" selector="{{CheckoutShippingSection.defaultShipping}}" userInput="{{SimpleTaxNY.state}}"/> + + <!-- Assert that taxes are applied correctly for NY --> + <waitForElementVisible stepKey="waitForOverviewVisible2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$8.37"/> + <click stepKey="expandTax" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxNY.rate}}%)"/> + <see stepKey="seeTotalIncl" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$108.36"/> + <see stepKey="seeTotalExcl" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$$virtualProduct1.price$$"/> + </test> + + <test name="StorefrontTaxQuoteCheckoutLoggedInSimple"> + <annotations> + <features value="Tax"/> + <stories value="Tax Calculation in One Page Checkout"/> + <title value="Tax for Simple Product Quote should be recalculated according to inputted data on Checkout flow for Logged in Customer"/> + <description value="Tax for Simple Product Quote should be recalculated according to inputted data on Checkout flow for Logged in Customer"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-256"/> + <group value="Tax"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + + <!-- Fill in rules to display tax in the cart --> + <actionGroup ref="editTaxConfigurationByUI" stepKey="fillDefaultTaxForms"/> + + <!-- Go to tax rule page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulePage"/> + <waitForPageLoad stepKey="waitForTaxRatePage"/> + <click stepKey="addNewTaxRate" selector="{{AdminGridMainControls.add}}"/> + <fillField stepKey="fillRuleName" selector="{{AdminTaxRulesSection.ruleName}}" userInput="SampleRule"/> + + <!-- Add NY and CA tax rules --> + <actionGroup ref="addNewTaxRateNoZip" stepKey="addNYTaxRate"> + <argument name="taxCode" value="SimpleTaxNY"/> + </actionGroup> + + <actionGroup ref="addNewTaxRateNoZip" stepKey="addCATaxRate"> + <argument name="taxCode" value="SimpleTaxCA"/> + </actionGroup> + + <click stepKey="clickSave" selector="{{AdminStoresMainActionsSection.saveButton}}"/> + + <!-- Fill out form for a new user with address --> + <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> + <argument name="Customer" value="Simple_US_Customer_NY"/> + </actionGroup> + + <actionGroup ref="EnterCustomerAddressInfo" stepKey="enterAddressInfo"> + <argument name="Address" value="US_Address_NY"/> + </actionGroup> + </before> + <after> + <!-- Go to the tax rule page and delete the row we created--> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulesPage"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteRule"> + <argument name="name" value="SampleRule"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Go to the tax rate page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRatesPage"/> + <waitForPageLoad stepKey="waitForRatesPage"/> + + <!-- Delete the two tax rates that were created --> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteNYRate"> + <argument name="name" value="{{SimpleTaxNY.state}}-{{SimpleTaxNY.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteCARate"> + <argument name="name" value="{{SimpleTaxCA.state}}-{{SimpleTaxCA.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Ensure tax wont be shown in the cart --> + <actionGroup ref="changeToDefaultTaxConfigurationUI" stepKey="changeToDefaultTaxConfiguration"/> + + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + </after> + + <!-- Go to the created product page and add it to the cart --> + <amOnPage url="$$simpleProduct1.sku$$.html" stepKey="goToSimpleProductPage"/> + <waitForPageLoad stepKey="waitForSimpleProductPage"/> + <click stepKey="addSimpleProductToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> + <waitForPageLoad stepKey="waitForProductAdded"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> + + <!-- Assert that taxes are applied correctly for NY --> + <amOnPage url="{{CheckoutPage.url}}" stepKey="goToCheckout"/> + <waitForPageLoad stepKey="waitForShippingSection"/> + <see stepKey="seeAddress" selector="{{CheckoutShippingSection.selectedShippingAddress}}" userInput="{{SimpleTaxNY.state}}"/> + <click stepKey="clickNext" selector="{{CheckoutShippingSection.next}}"/> + <waitForPageLoad stepKey="waitForReviewAndPayments"/> + + <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.30"/> + <click stepKey="expandTax" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxNY.rate}}%)"/> + <see stepKey="seeTotalIncl" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$138.30"/> + <see stepKey="seeTotalExcl" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$128.00"/> + + <!-- Go back to the shipping page and change the address --> + <click stepKey="goBackToShipping" selector="{{CheckoutShippingSection.shippingTab}}"/> + <click stepKey="addNewAddress" selector="{{CheckoutShippingSection.newAddressButton}}"/> + <waitForPageLoad stepKey="waitForAddressPopUp"/> + + <actionGroup ref="LoggedInCheckoutFillNewBillingAddressActionGroup" stepKey="changeAddress"> + <argument name="Address" value="US_Address_CA"/> + <argument name="classPrefix" value="._show"/> + </actionGroup> + <click stepKey="saveAddress" selector="{{CheckoutShippingSection.saveAddress}}"/> + + <waitForPageLoad stepKey="waitForAddressSaved"/> + <see stepKey="seeAddress2" selector="{{CheckoutShippingSection.selectedShippingAddress}}" userInput="{{SimpleTaxCA.state}}"/> + <click stepKey="clickNext2" selector="{{CheckoutShippingSection.next}}"/> + <waitForPageLoad stepKey="waitForReviewAndPayments2"/> + + <!-- Assert that taxes are applied correctly for CA --> + <waitForElementVisible stepKey="waitForOverviewVisible2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax2" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.15"/> + <click stepKey="expandTax2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent2" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxCA.rate}}%)"/> + <see stepKey="seeTotalIncl2" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$138.15"/> + <see stepKey="seeTotalExcl2" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$128.00"/> + </test> + + <test name="StorefrontTaxQuoteCheckoutGuestSimple"> + <annotations> + <features value="Tax"/> + <stories value="Tax Calculation in One Page Checkout"/> + <title value="Tax for Simple Product Quote should be recalculated according to inputted data on Checkout flow for Guest Customer"/> + <description value="Tax for Simple Product Quote should be recalculated according to inputted data on Checkout flow for Guest Customer"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-258"/> + <group value="Tax"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + + <!-- Fill in rules to display tax in the cart --> + <actionGroup ref="editTaxConfigurationByUI" stepKey="fillDefaultTaxForms"/> + + <!-- Go to tax rule page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulePage"/> + <waitForPageLoad stepKey="waitForTaxRatePage"/> + <click stepKey="addNewTaxRate" selector="{{AdminGridMainControls.add}}"/> + <fillField stepKey="fillRuleName" selector="{{AdminTaxRulesSection.ruleName}}" userInput="SampleRule"/> + + <!-- Add NY and CA tax rules --> + <actionGroup ref="addNewTaxRateNoZip" stepKey="addNYTaxRate"> + <argument name="taxCode" value="SimpleTaxNY"/> + </actionGroup> + + <actionGroup ref="addNewTaxRateNoZip" stepKey="addCATaxRate"> + <argument name="taxCode" value="SimpleTaxCA"/> + </actionGroup> + + <click stepKey="clickSave" selector="{{AdminStoresMainActionsSection.saveButton}}"/> + </before> + <after> + <!-- Go to the tax rule page and delete the row we created--> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulesPage"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteRule"> + <argument name="name" value="SampleRule"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Go to the tax rate page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRatesPage"/> + <waitForPageLoad stepKey="waitForRatesPage"/> + + <!-- Delete the two tax rates that were created --> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteNYRate"> + <argument name="name" value="{{SimpleTaxNY.state}}-{{SimpleTaxNY.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteCARate"> + <argument name="name" value="{{SimpleTaxCA.state}}-{{SimpleTaxCA.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Ensure tax wont be shown in the cart --> + <actionGroup ref="changeToDefaultTaxConfigurationUI" stepKey="changeToDefaultTaxConfiguration"/> + + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + </after> + + <!-- Go to the created product page and add it to the cart --> + <amOnPage url="$$simpleProduct1.sku$$.html" stepKey="goToSimpleProductPage"/> + <waitForPageLoad stepKey="waitForSimpleProductPage"/> + <click stepKey="addSimpleProductToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> + <waitForPageLoad stepKey="waitForProductAdded"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> + + <!-- Fill in address for CA --> + <amOnPage url="{{CheckoutPage.url}}" stepKey="goToCheckout"/> + <waitForPageLoad stepKey="waitForShippingSection"/> + <fillField selector="{{CheckoutShippingSection.email}}" userInput="{{Simple_US_Customer_CA.email}}" stepKey="enterEmail"/> + <waitForLoadingMaskToDisappear stepKey="waitEmailLoad" /> + <actionGroup ref="LoggedInCheckoutFillNewBillingAddressActionGroup" stepKey="changeAddress"> + <argument name="Address" value="US_Address_CA"/> + </actionGroup> + <click stepKey="clickNext" selector="{{CheckoutShippingSection.next}}"/> + <see stepKey="seeAddress" selector="{{CheckoutShippingSection.defaultShipping}}" userInput="{{SimpleTaxCA.state}}"/> + <see stepKey="seeShipTo" selector="{{CheckoutPaymentSection.shipToInfomation}}" userInput="{{SimpleTaxCA.state}}"/> + + <!-- Assert that taxes are applied correctly for CA --> + <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax2" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.15"/> + <click stepKey="expandTax2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent2" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxCA.rate}}%)"/> + <see stepKey="seeTotalIncl2" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$138.15"/> + <see stepKey="seeTotalExcl2" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$128.00"/> + + <!-- Go back to the shipping page and change the address --> + <click stepKey="goBackToShipping" selector="{{CheckoutShippingSection.shippingTab}}"/> + <actionGroup ref="LoggedInCheckoutFillNewBillingAddressActionGroup" stepKey="changeAddress2"> + <argument name="Address" value="US_Address_NY"/> + </actionGroup> + <click stepKey="clickNext2" selector="{{CheckoutShippingSection.next}}"/> + <see stepKey="seeShipTo2" selector="{{CheckoutPaymentSection.shipToInfomation}}" userInput="{{SimpleTaxNY.state}}"/> + + <!-- Assert that taxes are applied correctly for NY --> + <waitForElementVisible stepKey="waitForOverviewVisible2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.30"/> + <click stepKey="expandTax" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxNY.rate}}%)"/> + <see stepKey="seeTotalIncl" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$138.30"/> + <see stepKey="seeTotalExcl" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$128.00"/> + </test> + + <test name="StorefrontTaxQuoteCheckoutLoggedInVirtual"> + <annotations> + <features value="Tax"/> + <stories value="Tax Calculation in One Page Checkout"/> + <title value="Tax for Virtual Product Quote should be recalculated according to inputted data on Checkout flow for Logged in Customer"/> + <description value="Tax for Virtual Product Quote should be recalculated according to inputted data on Checkout flow for Logged in Customer"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-259"/> + <group value="Tax"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <createData entity="VirtualProduct" stepKey="virtualProduct1"/> + + <!-- Fill in rules to display tax in the cart --> + <actionGroup ref="editTaxConfigurationByUI" stepKey="fillDefaultTaxForms"/> + + <!-- Go to tax rule page --> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulePage"/> + <waitForPageLoad stepKey="waitForTaxRatePage"/> + <click stepKey="addNewTaxRate" selector="{{AdminGridMainControls.add}}"/> + <fillField stepKey="fillRuleName" selector="{{AdminTaxRulesSection.ruleName}}" userInput="SampleRule"/> + + <!-- Add NY and CA tax rules --> + <actionGroup ref="addNewTaxRateNoZip" stepKey="addNYTaxRate"> + <argument name="taxCode" value="SimpleTaxNY"/> + </actionGroup> + + <actionGroup ref="addNewTaxRateNoZip" stepKey="addCATaxRate"> + <argument name="taxCode" value="SimpleTaxCA"/> + </actionGroup> + + <click stepKey="clickSave" selector="{{AdminStoresMainActionsSection.saveButton}}"/> + + <!-- Fill out form for a new user with address --> + <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> + <argument name="Customer" value="Simple_US_Customer_NY"/> + </actionGroup> + + <actionGroup ref="EnterCustomerAddressInfo" stepKey="enterAddressInfo"> + <argument name="Address" value="US_Address_NY"/> + </actionGroup> + </before> + <after> + <!-- Go to the tax rule page and delete the row we created--> + <amOnPage url="{{AdminTaxRuleGridPage.url}}" stepKey="goToTaxRulesPage"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteRule"> + <argument name="name" value="SampleRule"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Go to the tax rate page --> + <amOnPage url="{{AdminTaxRateGridPage.url}}" stepKey="goToTaxRatesPage"/> + <waitForPageLoad stepKey="waitForRatesPage"/> + + <!-- Delete the two tax rates that were created --> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteNYRate"> + <argument name="name" value="{{SimpleTaxNY.state}}-{{SimpleTaxNY.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deleteCARate"> + <argument name="name" value="{{SimpleTaxCA.state}}-{{SimpleTaxCA.rate}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> + </actionGroup> + + <!-- Ensure tax wont be shown in the cart --> + <actionGroup ref="changeToDefaultTaxConfigurationUI" stepKey="changeToDefaultTaxConfiguration"/> + + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="virtualProduct1" stepKey="deleteVirtualProduct1"/> + </after> + + <!-- Go to the created product page and add it to the cart --> + <amOnPage url="$$virtualProduct1.sku$$.html" stepKey="goToVirtualProductPage"/> + <waitForPageLoad stepKey="waitForVirtualProductPage"/> + <click stepKey="addVirtualProductToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> + <waitForPageLoad stepKey="waitForProductAdded"/> + <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> + + <!-- Assert that taxes are applied correctly for NY --> + <amOnPage url="{{CheckoutPage.url}}" stepKey="goToCheckout"/> + <waitForPageLoad stepKey="waitForShippingSection"/> + <see stepKey="seeAddress" selector="{{CheckoutShippingSection.defaultShipping}}" userInput="{{SimpleTaxNY.state}}"/> + + <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$8.37"/> + <click stepKey="expandTax" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxNY.rate}}%)"/> + <see stepKey="seeTotalIncl" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$108.36"/> + <see stepKey="seeTotalExcl" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$$virtualProduct1.price$$"/> + + <!-- Change the address --> + <click stepKey="editAddress" selector="{{CheckoutShippingSection.editAddressButton}}"/> + <selectOption stepKey="addNewAddress" selector="{{CheckoutShippingSection.addressDropdown}}" userInput="New Address"/> + <waitForPageLoad stepKey="waitForNewAddressForm"/> + + <actionGroup ref="LoggedInCheckoutFillNewBillingAddressActionGroup" stepKey="changeAddress"> + <argument name="Address" value="US_Address_CA"/> + <argument name="classPrefix" value="[aria-hidden=false]"/> + </actionGroup> + <click stepKey="saveAddress" selector="{{CheckoutShippingSection.updateAddress}}"/> + + <waitForPageLoad stepKey="waitForAddressSaved"/> + <see stepKey="seeAddress2" selector="{{CheckoutShippingSection.defaultShipping}}" userInput="{{SimpleTaxCA.state}}"/> + + <!-- Assert that taxes are applied correctly for CA --> + <waitForElementVisible stepKey="waitForOverviewVisible2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTax2" selector="{{CheckoutPaymentSection.tax}}" userInput="$8.25"/> + <click stepKey="expandTax2" selector="{{CheckoutPaymentSection.tax}}"/> + <see stepKey="seeTaxPercent2" selector="{{CheckoutPaymentSection.taxPercentage}}" userInput="({{SimpleTaxCA.rate}}%)"/> + <see stepKey="seeTotalIncl2" selector="{{CheckoutPaymentSection.orderSummaryTotalIncluding}}" userInput="$108.24"/> + <see stepKey="seeTotalExcl2" selector="{{CheckoutPaymentSection.orderSummaryTotalExcluding}}" userInput="$$virtualProduct1.price$$"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json index fb47e3fbeba58..9a39b2518fe43 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tax/composer.json @@ -12,18 +12,18 @@ }, "require": { "magento/magento2-functional-testing-framework": "1.0.0", - "php": "~7.1.3||~7.2.0" - }, - "suggest": { "magento/magento2-functional-test-module-backend": "100.0.0-dev", "magento/magento2-functional-test-module-catalog": "100.0.0-dev", "magento/magento2-functional-test-module-checkout": "100.0.0-dev", "magento/magento2-functional-test-module-config": "100.0.0-dev", "magento/magento2-functional-test-module-customer": "100.0.0-dev", + "magento/magento2-functional-test-module-quote": "100.0.0-dev", + "php": "~7.1.3||~7.2.0" + }, + "suggest": { "magento/magento2-functional-test-module-directory": "100.0.0-dev", "magento/magento2-functional-test-module-eav": "100.0.0-dev", "magento/magento2-functional-test-module-page-cache": "100.0.0-dev", - "magento/magento2-functional-test-module-quote": "100.0.0-dev", "magento/magento2-functional-test-module-reports": "100.0.0-dev", "magento/magento2-functional-test-module-sales": "100.0.0-dev", "magento/magento2-functional-test-module-shipping": "100.0.0-dev", diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tinymce3/Test/AdminSwitchWYSIWYGOptionsTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tinymce3/Test/AdminSwitchWYSIWYGOptionsTest.xml index b6e4cdc61258d..350f3a77cbe5c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tinymce3/Test/AdminSwitchWYSIWYGOptionsTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Tinymce3/Test/AdminSwitchWYSIWYGOptionsTest.xml @@ -10,11 +10,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminSwitchWYSIWYGOptionsTest"> <annotations> - <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <features value="Cms"/> <stories value="MAGETWO-51829-Extensible list of WYSIWYG editors available in Magento"/> <group value="Cms"/> - <title value="Admin are able to switch between versions of TinyMCE."/> - <description value="Admin are able to switch between versions of TinyMCE."/> + <title value="Admin should able to switch between versions of TinyMCE"/> + <description value="Admin should able to switch between versions of TinyMCE"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-82936"/> <!--Skip because of issue MAGETWO-89417--> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml index 06b45227e61cb..da2239a0da85e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml @@ -9,7 +9,8 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="StorefrontAddMultipleStoreProductsToWishlistTest"> <annotations> - <title value="Add products to wishlist from different stores"/> + <features value="Wishlist"/> + <title value="Customer should be able to add products to wishlist from different stores"/> <description value="All products added to wishlist should be visible on any store. Even if product visibility was set to 'Not Visible Individually' for this store"/> <group value="wishlist"/> </annotations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/Test/StorefrontDeletePersistedWishlistTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/Test/StorefrontDeletePersistedWishlistTest.xml index 45fd0bb1a2038..7b9c40d7f3d31 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/Test/StorefrontDeletePersistedWishlistTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Wishlist/Test/StorefrontDeletePersistedWishlistTest.xml @@ -9,10 +9,10 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="StorefrontDeletePersistedWishlistTest"> <annotations> - <features value="Delete a persist wishlist for a customer"/> + <features value="Wishlist"/> <stories value="Delete a persist wishlist for a customer"/> - <title value="Delete a persist wishlist for a customer"/> - <description value="Delete a persist wishlist for a customer"/> + <title value="Customer should be able to delete a persistent wishlist"/> + <description value="Customer should be able to delete a persistent wishlist"/> <group value="wishlist"/> </annotations> <before> diff --git a/dev/tests/api-functional/testsuite/Magento/AsynchronousOperations/Api/OperationRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/AsynchronousOperations/Api/OperationRepositoryInterfaceTest.php new file mode 100644 index 0000000000000..8eab6c9fd8676 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/AsynchronousOperations/Api/OperationRepositoryInterfaceTest.php @@ -0,0 +1,124 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\AsynchronousOperations\Api; + +use Magento\Framework\Webapi\Rest\Request; +use Magento\TestFramework\TestCase\WebapiAbstract; +use Magento\Framework\Bulk\OperationInterface; + +class OperationRepositoryInterfaceTest extends WebapiAbstract +{ + const RESOURCE_PATH = '/V1/bulk'; + const SERVICE_NAME = 'asynchronousOperationsOperationRepositoryV1'; + + /** + * @magentoApiDataFixture Magento/AsynchronousOperations/_files/operation_searchable.php + */ + public function testGetListByBulkStartTime() + { + $searchCriteria = [ + 'searchCriteria' => [ + 'filter_groups' => [ + [ + 'filters' => [ + [ + 'field' => 'start_time', + 'value' => '2010-10-10 00:00:00', + 'condition_type' => 'lteq', + ], + ], + ], + ], + 'current_page' => 1, + ], + ]; + + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($searchCriteria), + 'httpMethod' => Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'operation' => self::SERVICE_NAME . 'GetList', + ], + ]; + + $response = $this->_webApiCall($serviceInfo, $searchCriteria); + + $this->assertArrayHasKey('search_criteria', $response); + $this->assertArrayHasKey('total_count', $response); + $this->assertArrayHasKey('items', $response); + + $this->assertEquals($searchCriteria['searchCriteria'], $response['search_criteria']); + $this->assertEquals(3, $response['total_count']); + $this->assertEquals(3, count($response['items'])); + + foreach ($response['items'] as $item) { + $this->assertEquals('bulk-uuid-searchable-6', $item['bulk_uuid']); + } + } + + /** + * @magentoApiDataFixture Magento/AsynchronousOperations/_files/operation_searchable.php + */ + public function testGetList() + { + $searchCriteria = [ + 'searchCriteria' => [ + 'filter_groups' => [ + [ + 'filters' => [ + [ + 'field' => 'bulk_uuid', + 'value' => 'bulk-uuid-searchable-6', + 'condition_type' => 'eq', + ], + ], + ], + [ + 'filters' => [ + [ + 'field' => 'status', + 'value' => OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, + 'condition_type' => 'eq', + ], + ], + ], + ], + 'current_page' => 1, + ], + ]; + + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($searchCriteria), + 'httpMethod' => Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'operation' => self::SERVICE_NAME . 'GetList', + ], + ]; + + $response = $this->_webApiCall($serviceInfo, $searchCriteria); + + $this->assertArrayHasKey('search_criteria', $response); + $this->assertArrayHasKey('total_count', $response); + $this->assertArrayHasKey('items', $response); + + $this->assertEquals($searchCriteria['searchCriteria'], $response['search_criteria']); + $this->assertEquals(1, $response['total_count']); + $this->assertEquals(1, count($response['items'])); + + foreach ($response['items'] as $item) { + $this->assertEquals('bulk-uuid-searchable-6', $item['bulk_uuid']); + } + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index e1e6ff79e75ce..e140305db4dcd 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -10,6 +10,7 @@ use Magento\Store\Model\Store; use Magento\CatalogInventory\Api\Data\StockItemInterface; use Magento\Store\Model\Website; +use Magento\Store\Model\WebsiteRepository; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; use Magento\Framework\Api\FilterBuilder; @@ -17,6 +18,7 @@ use Magento\Framework\Api\SortOrder; use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; +use Magento\Framework\Exception\NoSuchEntityException; /** * @magentoAppIsolation enabled @@ -136,6 +138,24 @@ public function productCreationProvider() ]; } + /** + * Load website by website code + * + * @param $websiteCode + * @return Website + */ + private function loadWebsiteByCode($websiteCode) + { + $websiteRepository = Bootstrap::getObjectManager()->get(WebsiteRepository::class); + try { + $website = $websiteRepository->get($websiteCode); + } catch (NoSuchEntityException $e) { + $this->fail("Couldn`t load website: {$websiteCode}"); + } + + return $website; + } + /** * Test removing association between product and website 1 * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php @@ -144,12 +164,7 @@ public function testUpdateWithDeleteWebsites() { $productBuilder[ProductInterface::SKU] = 'unique-simple-azaza'; /** @var Website $website */ - $website = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(Website::class); - $website->load('second_website', 'code'); - - if (!$website->getId()) { - $this->fail("Couldn`t load website"); - } + $website = $this->loadWebsiteByCode('second_website'); $websitesData = [ 'website_ids' => [ @@ -171,13 +186,6 @@ public function testUpdateWithDeleteWebsites() public function testDeleteAllWebsiteAssociations() { $productBuilder[ProductInterface::SKU] = 'unique-simple-azaza'; - /** @var Website $website */ - $website = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(Website::class); - $website->load('second_website', 'code'); - - if (!$website->getId()) { - $this->fail("Couldn`t load website"); - } $websitesData = [ 'website_ids' => [] @@ -198,14 +206,9 @@ public function testCreateWithMultipleWebsites() $productBuilder = $this->getSimpleProductData(); $productBuilder[ProductInterface::SKU] = 'test-test-sku'; $productBuilder[ProductInterface::TYPE_ID] = 'simple'; - /** @var Website $website */ - $website = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(Website::class); - $website->load('test_website', 'code'); + $website = $this->loadWebsiteByCode('test_website'); - if (!$website->getId()) { - $this->fail("Couldn`t load website"); - } $websitesData = [ 'website_ids' => [ 1, @@ -218,6 +221,84 @@ public function testCreateWithMultipleWebsites() $response[ProductInterface::EXTENSION_ATTRIBUTES_KEY]["website_ids"], $websitesData["website_ids"] ); + $this->deleteProduct($productBuilder[ProductInterface::SKU]); + } + + /** + * Add product associated with website that is not associated with default store + * + * @magentoApiDataFixture Magento/Store/_files/second_website_with_two_stores.php + */ + public function testCreateWithNonDefaultStoreWebsite() + { + $productBuilder = $this->getSimpleProductData(); + $productBuilder[ProductInterface::SKU] = 'test-sku-second-site-123'; + $productBuilder[ProductInterface::TYPE_ID] = 'simple'; + /** @var Website $website */ + $website = $this->loadWebsiteByCode('test'); + + $websitesData = [ + 'website_ids' => [ + $website->getId(), + ] + ]; + $productBuilder[ProductInterface::EXTENSION_ATTRIBUTES_KEY] = $websitesData; + $response = $this->saveProduct($productBuilder); + $this->assertEquals( + $websitesData["website_ids"], + $response[ProductInterface::EXTENSION_ATTRIBUTES_KEY]["website_ids"] + ); + $this->deleteProduct($productBuilder[ProductInterface::SKU]); + } + + /** + * Update product to be associated with website that is not associated with default store + * + * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php + * @magentoApiDataFixture Magento/Store/_files/second_website_with_two_stores.php + */ + public function testUpdateWithNonDefaultStoreWebsite() + { + $productBuilder[ProductInterface::SKU] = 'unique-simple-azaza'; + /** @var Website $website */ + $website = $this->loadWebsiteByCode('test'); + + $this->assertNotContains(Store::SCOPE_DEFAULT, $website->getStoreCodes()); + + $websitesData = [ + 'website_ids' => [ + $website->getId(), + ] + ]; + $productBuilder[ProductInterface::EXTENSION_ATTRIBUTES_KEY] = $websitesData; + $response = $this->updateProduct($productBuilder); + $this->assertEquals( + $websitesData["website_ids"], + $response[ProductInterface::EXTENSION_ATTRIBUTES_KEY]["website_ids"] + ); + } + + /** + * Update product without specifying websites + * + * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php + */ + public function testUpdateWithoutWebsiteIds() + { + $productBuilder[ProductInterface::SKU] = 'unique-simple-azaza'; + $originalProduct = $this->getProduct($productBuilder[ProductInterface::SKU]); + $newName = 'Updated Product'; + + $productBuilder[ProductInterface::NAME] = $newName; + $response = $this->updateProduct($productBuilder); + $this->assertEquals( + $newName, + $response[ProductInterface::NAME] + ); + $this->assertEquals( + $originalProduct[ProductInterface::EXTENSION_ATTRIBUTES_KEY]["website_ids"], + $response[ProductInterface::EXTENSION_ATTRIBUTES_KEY]["website_ids"] + ); } /** @@ -727,8 +808,7 @@ public function testGetList() */ public function testGetListWithFilteringByWebsite() { - $website = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(Website::class); - $website->load('test', 'code'); + $website = $this->loadWebsiteByCode('test'); $searchCriteria = [ 'searchCriteria' => [ 'filter_groups' => [ diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index dca3bf9abd182..0133b87e757bd 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -7,6 +7,7 @@ namespace Magento\GraphQl\Catalog; +use Magento\Catalog\Api\Data\CategoryInterface; use Magento\Framework\DataObject; use Magento\TestFramework\TestCase\GraphQlAbstract; use Magento\Catalog\Api\Data\ProductInterface; @@ -254,7 +255,6 @@ public function testCategoryProducts() default_group_id is_default } - } } } @@ -281,6 +281,54 @@ public function testCategoryProducts() $this->assertWebsites($firstProduct, $response['category']['products']['items'][0]['websites']); } + /** + * @magentoApiDataFixture Magento/Catalog/_files/categories.php + */ + public function testAnchorCategory() + { + /** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $categoryCollection */ + $categoryCollection = $this->objectManager->create( + \Magento\Catalog\Model\ResourceModel\Category\Collection::class + ); + $categoryCollection->addFieldToFilter('name', 'Category 1'); + $category = $categoryCollection->getFirstItem(); + /** @var \Magento\Framework\EntityManager\MetadataPool $entityManagerMetadataPool */ + $entityManagerMetadataPool = $this->objectManager->create(\Magento\Framework\EntityManager\MetadataPool::class); + $categoryLinkField = $entityManagerMetadataPool->getMetadata(CategoryInterface::class)->getLinkField(); + $categoryId = $category->getData($categoryLinkField); + $this->assertNotEmpty($categoryId, "Preconditions failed: category is not available."); + + $query = <<<QUERY +{ + category(id: {$categoryId}) { + name + products(sort: {sku: ASC}) { + total_count + items { + sku + } + } + } +} +QUERY; + + $response = $this->graphQlQuery($query); + $expectedResponse = [ + 'category' => [ + 'name' => 'Category 1', + 'products' => [ + 'total_count' => 3, + 'items' => [ + ['sku' => '12345'], + ['sku' => 'simple'], + ['sku' => 'simple-4'] + ] + ] + ] + ]; + $this->assertEquals($expectedResponse, $response); + } + /** * @param ProductInterface $product * @param array $actualResponse diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php index 65e044a5f005b..dc5a66fbb34ab 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php @@ -679,7 +679,7 @@ public function testFilterProductsByCategoryIds() products( filter: { - category_ids:{eq:"{$queryCategoryId}"} + category_id:{eq:"{$queryCategoryId}"} } pageSize:2 diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCreateTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCreateTest.php index 8c8130d2b3949..d8b3c5cac52aa 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCreateTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCreateTest.php @@ -43,13 +43,13 @@ public function testInvoke() 'qty' => $orderItem->getQtyOrdered(), 'additional_data' => null, 'description' => null, - 'entity_id' => null, + 'entity_id' => 1, 'name' => null, 'parent_id' => null, 'price' => null, 'product_id' => null, 'row_total' => null, - 'sku' => null, + 'sku' => 'simple', 'weight' => null, ], ]; diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentGetTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentGetTest.php index aaa7a5a6d4436..2b7e76aee0751 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentGetTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentGetTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Sales\Service\V1; +use Magento\Framework\Api\ExtensibleDataInterface; +use Magento\Framework\Api\SimpleDataObjectConverter; use Magento\TestFramework\TestCase\WebapiAbstract; /** @@ -57,7 +59,18 @@ public function testShipmentGet() unset($data['tracks']); foreach ($data as $key => $value) { if (!empty($value)) { - $this->assertEquals($shipment->getData($key), $value, $key); + if ($key === ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY) { + foreach ($value as $extensionAttributeKey => $extensionAttributeValue) { + $methodName = 'get' . + SimpleDataObjectConverter::snakeCaseToUpperCamelCase($extensionAttributeKey); + $this->assertEquals( + $shipment->getExtensionAttributes()->$methodName(), + $extensionAttributeValue + ); + } + } else { + $this->assertEquals($shipment->getData($key), $value, $key); + } } } $shipmentItem = $this->objectManager->get(\Magento\Sales\Model\Order\Shipment\Item::class); diff --git a/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/AsyncScheduleCustomRouteTest.php b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/AsyncScheduleCustomRouteTest.php new file mode 100644 index 0000000000000..4a56c4e0e6f77 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/WebapiAsync/Model/AsyncScheduleCustomRouteTest.php @@ -0,0 +1,257 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\WebapiAsync\Model; + +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Framework\Exception\NotFoundException; +use Magento\TestFramework\MessageQueue\PreconditionFailedException; +use Magento\TestFramework\MessageQueue\PublisherConsumerController; +use Magento\TestFramework\MessageQueue\EnvironmentPreconditionException; +use Magento\TestFramework\TestCase\WebapiAbstract; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Framework\Phrase; +use Magento\Framework\Registry; +use Magento\Framework\Webapi\Exception; +use Magento\Catalog\Api\ProductRepositoryInterface; + +/** + * Check async request for product creation service using custom route, scheduling bulk to rabbitmq + * running consumers and check async.operation.add consumer + * check if product was created by async requests + * + * @magentoAppIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class AsyncScheduleCustomRouteTest extends WebapiAbstract +{ + const ASYNC_RESOURCE_CUSTOM_PATH = '/asyncProducts'; + const ASYNC_CONSUMER_NAME = 'async.operations.all'; + + const KEY_TIER_PRICES = 'tier_prices'; + const KEY_SPECIAL_PRICE = 'special_price'; + const KEY_CATEGORY_LINKS = 'category_links'; + + const BULK_UUID_KEY = 'bulk_uuid'; + + protected $consumers = [ + self::ASYNC_CONSUMER_NAME, + ]; + + /** + * @var string[] + */ + private $skus = []; + + /** + * @var PublisherConsumerController + */ + private $publisherConsumerController; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + /** + * @var Registry + */ + private $registry; + + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->logFilePath = TESTS_TEMP_DIR . "/MessageQueueTestLog.txt"; + $this->registry = $this->objectManager->get(Registry::class); + + $params = array_merge_recursive( + \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppInitParams(), + ['MAGE_DIRS' => ['cache' => ['path' => TESTS_TEMP_DIR . '/cache']]] + ); + + /** @var PublisherConsumerController publisherConsumerController */ + $this->publisherConsumerController = $this->objectManager->create(PublisherConsumerController::class, [ + 'consumers' => $this->consumers, + 'logFilePath' => $this->logFilePath, + 'appInitParams' => $params, + ]); + $this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + + try { + $this->publisherConsumerController->initialize(); + } catch (EnvironmentPreconditionException $e) { + $this->markTestSkipped($e->getMessage()); + } catch (PreconditionFailedException $e) { + $this->fail( + $e->getMessage() + ); + } + + parent::setUp(); + } + + /** + * @dataProvider productCreationProvider + */ + public function testAsyncScheduleBulkByCustomRoute($product) + { + $this->_markTestAsRestOnly(); + $this->skus[] = $product['product'][ProductInterface::SKU]; + $this->clearProducts(); + + $response = $this->saveProductByCustomRoute($product); + $this->assertArrayHasKey(self::BULK_UUID_KEY, $response); + $this->assertNotNull($response[self::BULK_UUID_KEY]); + + $this->assertCount(1, $response['request_items']); + $this->assertEquals('accepted', $response['request_items'][0]['status']); + $this->assertFalse($response['errors']); + + //assert one products is created + try { + $this->publisherConsumerController->waitForAsynchronousResult( + [$this, 'assertProductCreation'], + [$product] + ); + } catch (PreconditionFailedException $e) { + $this->fail("Not all products were created"); + } + } + + public function tearDown() + { + $this->clearProducts(); + $this->publisherConsumerController->stopConsumers(); + parent::tearDown(); + } + + private function clearProducts() + { + $size = $this->objectManager->create(Collection::class) + ->addAttributeToFilter('sku', ['in' => $this->skus]) + ->load() + ->getSize(); + + if ($size == 0) { + return; + } + + $this->registry->unregister('isSecureArea'); + $this->registry->register('isSecureArea', true); + try { + foreach ($this->skus as $sku) { + $this->productRepository->deleteById($sku); + } + } catch (\Exception $e) { + throw $e; + //nothing to delete + } + $this->registry->unregister('isSecureArea'); + + $size = $this->objectManager->create(Collection::class) + ->addAttributeToFilter('sku', ['in' => $this->skus]) + ->load() + ->getSize(); + + if ($size > 0) { + throw new Exception(new Phrase("Collection size after clearing the products: %size", ['size' => $size])); + } + } + + /** + * @return array + */ + public function productCreationProvider() + { + $productBuilder = function ($data) { + return array_replace_recursive( + $this->getSimpleProductData(), + $data + ); + }; + + return [ + [ + [ + 'product' => + $productBuilder([ + ProductInterface::TYPE_ID => 'simple', + ProductInterface::SKU => 'psku-test-1', + ]), + ], + ], + [ + [ + 'product' => $productBuilder([ + ProductInterface::TYPE_ID => 'virtual', + ProductInterface::SKU => 'psku-test-2', + ]), + ], + ], + ]; + } + + /** + * Get Simple Product Data + * + * @param array $productData + * @return array + */ + private function getSimpleProductData($productData = []) + { + return [ + ProductInterface::SKU => isset($productData[ProductInterface::SKU]) + ? $productData[ProductInterface::SKU] : uniqid('sku-', true), + ProductInterface::NAME => isset($productData[ProductInterface::NAME]) + ? $productData[ProductInterface::NAME] : uniqid('sku-', true), + ProductInterface::VISIBILITY => 4, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::PRICE => 3.62, + ProductInterface::STATUS => 1, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::ATTRIBUTE_SET_ID => 4, + 'custom_attributes' => [ + ['attribute_code' => 'cost', 'value' => ''], + ['attribute_code' => 'description', 'value' => 'Description'], + ], + ]; + } + + /** + * @param $requestData + * @param string|null $storeCode + * @return mixed + */ + private function saveProductByCustomRoute($requestData, $storeCode = null) + { + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::ASYNC_RESOURCE_CUSTOM_PATH, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, + ], + ]; + + return $this->_webApiCall($serviceInfo, $requestData, null, $storeCode); + } + + public function assertProductCreation() + { + $collection = $this->objectManager->create(Collection::class) + ->addAttributeToFilter('sku', ['in' => $this->skus]) + ->load(); + $size = $collection->getSize(); + + return $size == count($this->skus); + } +} diff --git a/dev/tests/functional/composer.json b/dev/tests/functional/composer.json index da431fcf8a252..e49824d17df80 100644 --- a/dev/tests/functional/composer.json +++ b/dev/tests/functional/composer.json @@ -4,7 +4,7 @@ }, "require": { "php": "~7.1.3||~7.2.0", - "magento/mtf": "1.0.0-rc60", + "magento/mtf": "1.0.0-rc61", "allure-framework/allure-phpunit": "~1.2.0", "doctrine/annotations": "1.4.*", "phpunit/phpunit": "~6.5.0", diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderBackendTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderBackendTest.xml index 8ffcab68cdc62..acf15c0e28252 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderBackendTest.xml +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderBackendTest.xml @@ -27,8 +27,8 @@ <data name="creditCard/data/payment_code" xsi:type="string">braintree</data> <data name="configData" xsi:type="string">braintree</data> <data name="status" xsi:type="string">Processing</data> - <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Hold, Invoice, Ship, Reorder, Edit</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> + <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Invoice, Reorder, Edit</data> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" /> @@ -55,9 +55,9 @@ <data name="creditCard/dataset" xsi:type="string">visa_default</data> <data name="creditCard/data/payment_code" xsi:type="string">braintree</data> <data name="configData" xsi:type="string">braintree, braintree_sale</data> - <data name="status" xsi:type="string">Processing</data> - <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Hold, Ship, Reorder</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> + <data name="status" xsi:type="string">Complete</data> + <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Reorder</data> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" /> @@ -83,7 +83,7 @@ <data name="creditCard/dataset" xsi:type="string">visa_braintree_fraud_rejected</data> <data name="configData" xsi:type="string">braintree</data> <data name="status" xsi:type="string">Processing</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" /> </variation> diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Page/Adminhtml/CatalogRuleNew.xml b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Page/Adminhtml/CatalogRuleNew.xml index 1823dd1e1bbe2..ba4ff8d42d951 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Page/Adminhtml/CatalogRuleNew.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Page/Adminhtml/CatalogRuleNew.xml @@ -9,6 +9,6 @@ <page name="CatalogRuleNew" area="Adminhtml" mca="catalog_rule/promo_catalog/new" module="Magento_CatalogRule"> <block name="formPageActions" class="Magento\CatalogRule\Test\Block\Adminhtml\FormPageActions" locator=".page-main-actions" strategy="css selector"/> <block name="editForm" class="Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\PromoForm" locator="[id='page:main-container']" strategy="css selector"/> - <block name="modalBlock" class="Magento\Ui\Test\Block\Adminhtml\Modal" locator="._show[data-role=modal][style='z-index: 900;']" strategy="css selector"/> + <block name="modalBlock" class="Magento\Ui\Test\Block\Adminhtml\Modal" locator="._show[data-role=modal][style='z-index: 902;']" strategy="css selector"/> </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertMinicartEmpty.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertMinicartEmpty.php index 65a2b7879af8a..bb1f68c2d1278 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertMinicartEmpty.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertMinicartEmpty.php @@ -27,6 +27,7 @@ class AssertMinicartEmpty extends AbstractConstraint public function processAssert( CmsIndex $cmsIndex ) { + $cmsIndex->open(); \PHPUnit\Framework\Assert::assertEquals( self::TEXT_EMPTY_MINICART, $cmsIndex->getCartSidebarBlock()->getEmptyMessage(), diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml index 5e08ad3097ed3..b999900042c37 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml @@ -19,7 +19,7 @@ <data name="shipping/shipping_method" xsi:type="string">Fixed</data> <data name="payment/method" xsi:type="string">checkmo</data> <data name="configData" xsi:type="string">checkmo, disable_guest_checkout, disable_customer_redirect_after_logging</data> - <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> </variation> <variation name="OnePageCheckoutUsingRegisterLink" summary="Customer is redirected to checkout on login if guest is disabled, flow with registration new Customer" ticketId="MAGETWO-49917"> <data name="issue" xsi:type="string">MAGETWO-59816: Redirect works improperly in a browser incognito mode</data> @@ -35,7 +35,7 @@ <data name="shippingAddress/dataset" xsi:type="string">US_address_1_without_email</data> <data name="payment/method" xsi:type="string">checkmo</data> <data name="configData" xsi:type="string">checkmo, disable_guest_checkout, disable_customer_redirect_after_logging, enable_https_frontend_only</data> - <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> </variation> <variation name="OnePageCheckoutTestVariation1" summary="Checkout as UK guest with virtual product and downloadable product using coupon for not logged in customers"> <data name="tag" xsi:type="string">severity:S0</data> @@ -51,7 +51,6 @@ <data name="status" xsi:type="string">Pending</data> <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Cancel, Hold, Invoice, Edit</data> <data name="configData" xsi:type="string">checkmo_specificcountry_gb</data> - <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> @@ -70,10 +69,10 @@ <item name="grandTotal" xsi:type="string">285.00</item> </data> <data name="payment/method" xsi:type="string">banktransfer</data> - <data name="status" xsi:type="string">Pending</data> - <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Cancel, Hold, Ship, Invoice, Edit</data> + <data name="status" xsi:type="string">Processing</data> + <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Cancel, Hold, Invoice, Edit</data> <data name="configData" xsi:type="string">banktransfer</data> - <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> @@ -93,10 +92,10 @@ <item name="grandTotal" xsi:type="string">375.00</item> </data> <data name="payment/method" xsi:type="string">banktransfer</data> - <data name="status" xsi:type="string">Pending</data> - <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Cancel, Hold, Ship, Invoice, Edit</data> + <data name="status" xsi:type="string">Precessing</data> + <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Cancel, Hold, Invoice, Edit</data> <data name="configData" xsi:type="string">banktransfer_specificcountry_gb, can_subtract_and_can_back_in_stock</data> - <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductsOutOfStock" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductsQtyAndStockStatusInAdminPanel" /> @@ -123,7 +122,7 @@ <data name="billingCheckboxState" xsi:type="string">Yes</data> <data name="payment/method" xsi:type="string">checkmo</data> <data name="configData" xsi:type="string">checkmo</data> - <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal"/> </variation> @@ -149,7 +148,7 @@ <data name="refresh" xsi:type="boolean">true</data> <data name="payment/method" xsi:type="string">checkmo</data> <data name="configData" xsi:type="string">checkmo, freeshipping_minimum_order_amount_100</data> - <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderAddresses" /> @@ -168,7 +167,6 @@ <data name="status" xsi:type="string">Pending</data> <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Hold, Invoice, Edit</data> <data name="configData" xsi:type="string">zero_subtotal_checkout</data> - <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> @@ -185,9 +183,9 @@ <item name="grandTotal" xsi:type="string">375</item> </data> <data name="payment/method" xsi:type="string">checkmo</data> - <data name="status" xsi:type="string">Pending</data> + <data name="status" xsi:type="string">Processing</data> <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Cancel, Hold, Invoice, Edit</data> - <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Checkout\Test\Constraint\AssertCartIsEmpty" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> @@ -208,7 +206,7 @@ <item name="grandTotal" xsi:type="string">565.00</item> </data> <data name="payment/method" xsi:type="string">checkmo</data> - <constraint name="Magento\Customer\Test\Constraint\AssertCustomerRedirectToDashboard" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation9" summary="One Page Checkout Products with different shipping/billing address and Tier Prices" ticketId="MAGETWO-42604"> @@ -225,7 +223,7 @@ </data> <data name="payment/method" xsi:type="string">banktransfer</data> <data name="configData" xsi:type="string">banktransfer_specificcountry_gb</data> - <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" /> <constraint name="Magento\Customer\Test\Constraint\AssertCustomerDefaultAddressFrontendAddressBook" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/PlaceOrderStep.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/PlaceOrderStep.php index 13b8b9a1405fa..964f8f366f223 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/PlaceOrderStep.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/PlaceOrderStep.php @@ -7,9 +7,11 @@ namespace Magento\Checkout\Test\TestStep; use Magento\Checkout\Test\Constraint\AssertGrandTotalOrderReview; +use Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage; use Magento\Checkout\Test\Page\CheckoutOnepage; use Magento\Checkout\Test\Page\CheckoutOnepageSuccess; use Magento\Mtf\Fixture\FixtureFactory; +use Magento\Mtf\ObjectManager; use Magento\Mtf\TestStep\TestStepInterface; use Magento\Sales\Test\Fixture\OrderInjectable; @@ -32,6 +34,13 @@ class PlaceOrderStep implements TestStepInterface */ private $assertGrandTotalOrderReview; + /** + * Assert that order success message is correct. + * + * @var AssertOrderSuccessPlacedMessage + */ + private $assertOrderSuccessPlacedMessage; + /** * One page checkout success page. * @@ -75,6 +84,7 @@ class PlaceOrderStep implements TestStepInterface * @param array $products * @param array $prices * @param OrderInjectable|null $order + * @param AssertOrderSuccessPlacedMessage $assertOrderSuccessPlacedMessage */ public function __construct( CheckoutOnepage $checkoutOnepage, @@ -83,7 +93,8 @@ public function __construct( FixtureFactory $fixtureFactory, array $products = [], array $prices = [], - OrderInjectable $order = null + OrderInjectable $order = null, + AssertOrderSuccessPlacedMessage $assertOrderSuccessPlacedMessage = null ) { $this->checkoutOnepage = $checkoutOnepage; $this->assertGrandTotalOrderReview = $assertGrandTotalOrderReview; @@ -92,6 +103,8 @@ public function __construct( $this->products = $products; $this->prices = $prices; $this->order = $order; + $this->assertOrderSuccessPlacedMessage = $assertOrderSuccessPlacedMessage + ?: ObjectManager::getInstance()->create(AssertOrderSuccessPlacedMessage::class); } /** @@ -106,6 +119,7 @@ public function run() } $this->checkoutOnepage->getPaymentBlock()->getSelectedPaymentMethodBlock()->clickPlaceOrder(); $orderId = $this->checkoutOnepageSuccess->getSuccessBlock()->getGuestOrderId(); + $this->assertOrderSuccessPlacedMessage->processAssert($this->checkoutOnepageSuccess); $data = [ 'id' => $orderId, 'entity_id' => ['products' => $this->products] diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/testcase.xml index 0c8fbd5f03f9e..f0b0194039a34 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/testcase.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/etc/testcase.xml @@ -38,7 +38,8 @@ <step name="fillBillingInformation" module="Magento_Checkout" next="refreshPage" /> <step name="refreshPage" module="Magento_Checkout" next="placeOrder" /> <step name="placeOrder" module="Magento_Checkout" next="createCustomerAccount" /> - <step name="createCustomerAccount" module="Magento_Checkout" /> + <step name="createCustomerAccount" module="Magento_Checkout" next="createShipment" /> + <step name="createShipment" module="Magento_Sales"/> </scenario> <scenario name="OnePageCheckoutJsValidationTest" firstStep="setupConfiguration"> <step name="setupConfiguration" module="Magento_Config" next="createProducts" /> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php index e25a5c1f719d0..1ef9267e73785 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php @@ -69,6 +69,7 @@ public function createAccount() */ public function loginCustomer(Customer $customer) { + sleep(10); $this->fill($customer); $this->_rootElement->find($this->login)->click(); $this->waitForElementNotVisible($this->loadingMask); diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Actions.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Actions.php index 573f28f09b78c..7a6903ef47aac 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Actions.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Actions.php @@ -137,6 +137,16 @@ class Actions extends Block */ protected $confirmModal = '.confirm._show[data-role=modal]'; + /** + * Is shipment can be created. + * + * @return bool + */ + public function canShip() + { + return $this->_rootElement->find($this->ship)->isVisible(); + } + /** * Ship order. * diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendPartOneTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendPartOneTest.xml index f5646ac543213..0a5958b506a43 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendPartOneTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendPartOneTest.xml @@ -19,10 +19,10 @@ <item name="grandTotal" xsi:type="string">425.00</item> </data> <data name="payment/method" xsi:type="string">cashondelivery</data> - <data name="status" xsi:type="string">Pending</data> - <data name="orderButtonsAvailable" xsi:type="string">Back, Reorder, Cancel, Send Email, Hold, Invoice, Ship, Edit</data> + <data name="status" xsi:type="string">Processing</data> + <data name="orderButtonsAvailable" xsi:type="string">Back, Reorder, Cancel, Send Email, Invoice, Edit</data> <data name="configData" xsi:type="string">cashondelivery</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid" /> @@ -42,7 +42,6 @@ <data name="status" xsi:type="string">Pending</data> <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Hold, Invoice, Edit</data> <data name="configData" xsi:type="string">checkmo_specificcountry_gb</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid" /> @@ -59,10 +58,10 @@ <item name="grandTotal" xsi:type="string">565.00</item> </data> <data name="payment/method" xsi:type="string">banktransfer</data> - <data name="status" xsi:type="string">Pending</data> - <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Hold, Reorder, Invoice, Edit</data> + <data name="status" xsi:type="string">Processing</data> + <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Reorder, Invoice, Edit</data> <data name="configData" xsi:type="string">banktransfer</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid" /> @@ -84,7 +83,6 @@ <data name="status" xsi:type="string">Pending</data> <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Hold, Invoice, Edit</data> <data name="configData" xsi:type="string">freeshipping_specificcountry_gb, banktransfer</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid" /> @@ -103,10 +101,10 @@ </data> <data name="payment/method" xsi:type="string">purchaseorder</data> <data name="payment/po_number" xsi:type="string">123456</data> - <data name="status" xsi:type="string">Pending</data> - <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Hold, Invoice, Reorder, Edit</data> + <data name="status" xsi:type="string">Processing</data> + <data name="orderButtonsAvailable" xsi:type="string">Back, Cancel, Send Email, Invoice, Reorder, Edit</data> <data name="configData" xsi:type="string">purchaseorder</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid" /> @@ -127,7 +125,7 @@ <item name="grandTotal" xsi:type="string">21.91</item> </data> <data name="payment/method" xsi:type="string">checkmo</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="CreateOrderBackendTestVariation7" summary="Create Order for New Customer in Admin with Offline Payment Method" ticketId="MAGETWO-12520"> @@ -145,7 +143,7 @@ <item name="grandTotal" xsi:type="string">21.91</item> </data> <data name="payment/method" xsi:type="string">checkmo</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Customer\Test\Constraint\AssertCustomerForm" /> </variation> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml index 439b8a4492a1a..c4e03b94d2ada 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml @@ -19,7 +19,7 @@ </data> <data name="payment/method" xsi:type="string">cashondelivery</data> <data name="configData" xsi:type="string">cashondelivery</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductsOutOfStock" /> </variation> @@ -35,7 +35,7 @@ </data> <data name="payment/method" xsi:type="string">cashondelivery</data> <data name="configData" xsi:type="string">cashondelivery</data> - <constraint name="Magento\Sales\Test\Constraint\AssertOrderSuccessCreateMessage" /> + <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertReorderButtonIsNotVisibleOnFrontend" /> </variation> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateShipmentStep.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateShipmentStep.php index 79abd438a1f2e..dcee66b44646e 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateShipmentStep.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateShipmentStep.php @@ -99,13 +99,21 @@ public function run() { $this->orderIndex->open(); $this->orderIndex->getSalesOrderGrid()->searchAndOpen(['id' => $this->order->getId()]); - $this->salesOrderView->getPageActions()->ship(); - if (!empty($this->data)) { - $this->orderShipmentNew->getFormBlock()->fillData($this->data, $this->order->getEntityId()['products']); + $shipmentIds = []; + /** + * As this step is used in general scenarios and not all test cases has shippable items(ex: virtual product) + * we need to check, if it possible to create shipment for given order. + */ + if ($this->salesOrderView->getPageActions()->canShip()) { + $this->salesOrderView->getPageActions()->ship(); + if (!empty($this->data)) { + $this->orderShipmentNew->getFormBlock()->fillData($this->data, $this->order->getEntityId()['products']); + } + $this->orderShipmentNew->getFormBlock()->submit(); + $shipmentIds = $this->getShipmentIds(); } - $this->orderShipmentNew->getFormBlock()->submit(); - return ['shipmentIds' => $this->getShipmentIds()]; + return ['shipmentIds' => $shipmentIds]; } /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/etc/testcase.xml index c7c4a2276e4b7..1420255b9c86d 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/etc/testcase.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/etc/testcase.xml @@ -36,7 +36,8 @@ <step name="fillShippingAddress" module="Magento_Sales" next="selectShippingMethodForOrder" /> <step name="selectShippingMethodForOrder" module="Magento_Sales" next="selectPaymentMethodForOrder" /> <step name="selectPaymentMethodForOrder" module="Magento_Sales" next="submitOrder" /> - <step name="submitOrder" module="Magento_Sales" /> + <step name="submitOrder" module="Magento_Sales" next="createShipment"/> + <step name="createShipment" module="Magento_Sales"/> </scenario> <scenario name="CreateOrderBackendPartOneTest" firstStep="setupConfiguration"> <step name="setupConfiguration" module="Magento_Config" next="createProducts" /> @@ -54,7 +55,8 @@ <step name="fillShippingAddress" module="Magento_Sales" next="selectShippingMethodForOrder" /> <step name="selectShippingMethodForOrder" module="Magento_Sales" next="selectPaymentMethodForOrder" /> <step name="selectPaymentMethodForOrder" module="Magento_Sales" next="submitOrder" /> - <step name="submitOrder" module="Magento_Sales" /> + <step name="submitOrder" module="Magento_Sales" next="createShipment" /> + <step name="createShipment" module="Magento_Sales"/> </scenario> <scenario name="VoidAuthorizationTest" firstStep="setupConfiguration"> <step name="setupConfiguration" module="Magento_Config" next="createProducts" /> @@ -145,7 +147,8 @@ <scenario name="CreateCreditMemoEntityTest" firstStep="setupConfiguration"> <step name="setupConfiguration" module="Magento_Config" next="createOrder" /> <step name="createOrder" module="Magento_Sales" next="createInvoice" /> - <step name="createInvoice" module="Magento_Sales" next="createCreditMemo" /> + <step name="createInvoice" module="Magento_Sales" next="createShipment" /> + <step name="createShipment" module="Magento_Sales" next="createCreditMemo" /> <step name="createCreditMemo" module="Magento_Sales" /> </scenario> </config> diff --git a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/BulkManagementTest.php b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/BulkManagementTest.php index 940eb769298b9..5ecc274c5bbb8 100644 --- a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/BulkManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/Model/BulkManagementTest.php @@ -6,7 +6,6 @@ namespace Magento\AsynchronousOperations\Model; use Magento\AsynchronousOperations\Api\Data\BulkSummaryInterface; -use Magento\AsynchronousOperations\Api\Data\DetailedOperationStatusInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\ObjectManagerInterface; use Magento\AsynchronousOperations\Api\Data\OperationInterface; @@ -136,7 +135,7 @@ private function getStoredOperationData() { /** @var MetadataPool $metadataPool */ $metadataPool = $this->objectManager->get(MetadataPool::class); - $operationMetadata = $metadataPool->getMetadata(DetailedOperationStatusInterface::class); + $operationMetadata = $metadataPool->getMetadata(OperationInterface::class); /** @var ResourceConnection $resourceConnection */ $resourceConnection = $this->objectManager->get(ResourceConnection::class); $connection = $resourceConnection->getConnectionByName($operationMetadata->getEntityConnectionName()); diff --git a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php index 787d2c10a44c4..c6c58d47e5af4 100644 --- a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php +++ b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/bulk.php @@ -44,7 +44,7 @@ 'user_id' => 1, 'description' => 'Bulk Description', 'operation_count' => 2, - ] + ], ]; // Only processed operations are saved into database (i.e. operations that are not in 'open' state) $operations = [ @@ -88,7 +88,6 @@ 'error_code' => 2222, 'result_message' => 'Entity with ID=4 does not exist', ], - ]; $bulkQuery = "INSERT INTO {$bulkTable} (`uuid`, `user_id`, `description`, `operation_count`)" diff --git a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/operation_searchable.php b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/operation_searchable.php new file mode 100644 index 0000000000000..e74f995f8b57b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/operation_searchable.php @@ -0,0 +1,69 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Framework\Bulk\OperationInterface; + +/** + * @var $resource Magento\Framework\App\ResourceConnection + */ +$resource = Bootstrap::getObjectManager()->get(\Magento\Framework\App\ResourceConnection::class); +$connection = $resource->getConnection(); +$bulkTable = $resource->getTableName('magento_bulk'); +$operationTable = $resource->getTableName('magento_operation'); + +$bulks = [ + 'started_searchable' => [ + 'uuid' => 'bulk-uuid-searchable-6', + 'user_id' => 1, + 'description' => 'Bulk Description', + 'operation_count' => 3, + 'start_time' => '2009-10-10 00:00:00', + ], +]; +// Only processed operations are saved into database (i.e. operations that are not in 'open' state) +$operations = [ + [ + 'bulk_uuid' => 'bulk-uuid-searchable-6', + 'topic_name' => 'topic-5', + 'serialized_data' => json_encode(['entity_id' => 5]), + 'status' => OperationInterface::STATUS_TYPE_COMPLETE, + 'error_code' => null, + 'result_message' => null, + ], + [ + 'bulk_uuid' => 'bulk-uuid-searchable-6', + 'topic_name' => 'topic-5', + 'serialized_data' => json_encode(['entity_id' => 5, 'meta_information' => 'Test']), + 'status' => OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED, + 'error_code' => 1111, + 'result_message' => 'Something went wrong during your request', + ], + [ + 'bulk_uuid' => 'bulk-uuid-searchable-6', + 'topic_name' => 'topic-5', + 'serialized_data' => json_encode(['entity_id' => 5]), + 'status' => OperationInterface::STATUS_TYPE_RETRIABLY_FAILED, + 'error_code' => 2222, + 'result_message' => 'Entity with ID=4 does not exist', + ], + +]; + +$bulkQuery = "INSERT INTO {$bulkTable} (`uuid`, `user_id`, `description`, `operation_count`, `start_time`)" + . " VALUES (:uuid, :user_id, :description, :operation_count, :start_time);"; +foreach ($bulks as $bulk) { + $connection->query($bulkQuery, $bulk); +} + +$operationQuery = "INSERT INTO {$operationTable}" + . " (`bulk_uuid`, `topic_name`, `serialized_data`, `status`, `error_code`, `result_message`)" + . " VALUES (:bulk_uuid, :topic_name, :serialized_data, :status, :error_code, :result_message);"; +foreach ($operations as $operation) { + $connection->query($operationQuery, $operation); +} diff --git a/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/operation_searchable_rollback.php b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/operation_searchable_rollback.php new file mode 100644 index 0000000000000..268f159c125f2 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/AsynchronousOperations/_files/operation_searchable_rollback.php @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +// when bulks are removed, acknowledged bulk table will be cleared too. +require __DIR__ . '/bulk_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/quote_with_bundle_and_options.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/quote_with_bundle_and_options.php new file mode 100644 index 0000000000000..03949115ea62c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/quote_with_bundle_and_options.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; + +require __DIR__ . 'product_with_multiple_options.php'; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = $objectManager->create(\Magento\Catalog\Model\Product::class); +$product->load(3); + +/** @var $typeInstance \Magento\Bundle\Model\Product\Type */ +$typeInstance = $product->getTypeInstance(); +$typeInstance->setStoreFilter($product->getStoreId(), $product); +$optionCollection = $typeInstance->getOptionsCollection($product); + +$bundleOptions = []; +$bundleOptionsQty = []; +foreach ($optionCollection as $option) { + /** @var $option \Magento\Bundle\Model\Option */ + $selectionsCollection = $typeInstance->getSelectionsCollection([$option->getId()], $product); + if ($option->isMultiSelection()) { + $bundleOptions[$option->getId()] = array_column($selectionsCollection->toArray(), 'selection_id'); + } else { + $bundleOptions[$option->getId()] = $selectionsCollection->getFirstItem()->getSelectionId(); + } + $bundleOptionsQty[$option->getId()] = 1; +} + +$requestInfo = new \Magento\Framework\DataObject( + [ + 'product' => $product->getId(), + 'bundle_option' => $bundleOptions, + 'bundle_option_qty' => $bundleOptionsQty, + 'qty' => 1, + ] +); + +/** @var $cart \Magento\Checkout\Model\Cart */ +$cart = Bootstrap::getObjectManager()->create(\Magento\Checkout\Model\Cart::class); +$cart->addProduct($product, $requestInfo); +$cart->getQuote()->setReservedOrderId('test_cart_with_bundle_and_options'); +$cart->save(); + +/** @var $objectManager \Magento\TestFramework\ObjectManager */ +$objectManager = Bootstrap::getObjectManager(); +$objectManager->removeSharedInstance(\Magento\Checkout\Model\Session::class); diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/quote_with_bundle_and_options_rollback.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/quote_with_bundle_and_options_rollback.php new file mode 100644 index 0000000000000..d32d6fab33319 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/quote_with_bundle_and_options_rollback.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var $objectManager \Magento\TestFramework\ObjectManager */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$quote = $objectManager->create(\Magento\Quote\Model\Quote::class); +$quote->load('test_cart_with_bundle_and_options', 'reserved_order_id'); +$quote->delete(); + +/** @var \Magento\Quote\Model\QuoteIdMask $quoteIdMask */ +$quoteIdMask = $objectManager->create(\Magento\Quote\Model\QuoteIdMask::class); +$quoteIdMask->delete($quote->getId()); + +require __DIR__ . 'product_with_multiple_options_rollback.php'; + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Captcha/Observer/ResetAttemptForBackendObserverTest.php b/dev/tests/integration/testsuite/Magento/Captcha/Observer/ResetAttemptForBackendObserverTest.php new file mode 100644 index 0000000000000..c0a720229a00d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Captcha/Observer/ResetAttemptForBackendObserverTest.php @@ -0,0 +1,60 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Captcha\Observer; + +use Magento\Captcha\Model\ResourceModel\Log as CaptchaLog; +use Magento\Captcha\Model\ResourceModel\LogFactory; +use Magento\Framework\Event\ManagerInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\User\Model\User; +use Magento\User\Model\UserFactory; + +/** + * Class ResetAttemptForBackendObserverTest + * + * Test for checking that the admin login attempts are removed after a successful login + */ +class ResetAttemptForBackendObserverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + public function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + } + + /** + * @magentoDataFixture Magento/Captcha/_files/failed_logins_backend.php + */ + public function testLoginAttemptsRemovedAfterSuccessfulLogin() + { + $login = 'mageadmin'; + $userFactory = $this->objectManager->get(UserFactory::class); + $captchaLogFactory = $this->objectManager->get(LogFactory::class); + $eventManager = $this->objectManager->get(ManagerInterface::class); + + /** @var User $user */ + $user = $userFactory->create(); + $user->setUserName($login); + + $eventManager->dispatch( + 'backend_auth_user_login_success', + ['user' => $user] + ); + + /** + * @var CaptchaLog $captchaLog + */ + $captchaLog = $captchaLogFactory->create(); + + self::assertEquals(0, $captchaLog->countAttemptsByUserLogin($login)); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend.php b/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend.php new file mode 100644 index 0000000000000..7130cdfca57d7 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend.php @@ -0,0 +1,17 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Captcha\Model\ResourceModel\LogFactory; +use Magento\Captcha\Model\ResourceModel\Log; + +$objectManager = Bootstrap::getObjectManager(); +$logFactory = $objectManager->get(LogFactory::class); + +/** @var Log $captchaLog */ +$captchaLog = $logFactory->create(); +$captchaLog->logAttempt('mageadmin'); diff --git a/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend_rollback.php b/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend_rollback.php new file mode 100644 index 0000000000000..12a16027e1e5c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend_rollback.php @@ -0,0 +1,17 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Captcha\Model\ResourceModel\LogFactory; +use Magento\Captcha\Model\ResourceModel\Log; + +$objectManager = Bootstrap::getObjectManager(); +$logFactory = $objectManager->get(LogFactory::class); + +/** @var Log $captchaLog */ +$captchaLog = $logFactory->create(); +$captchaLog->deleteUserAttempts('mageadmin'); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Console/Command/ProductAttributesCleanUpTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Console/Command/ProductAttributesCleanUpTest.php index 88b59570457d3..4b6a2a40aa129 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Console/Command/ProductAttributesCleanUpTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Console/Command/ProductAttributesCleanUpTest.php @@ -107,8 +107,6 @@ private function prepareAdditionalStore() ->setGroupId($storeGroup->getId()) ->save(); - /* Refresh stores memory cache */ - $this->objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)->reinitStores(); return $store; } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php index fdc85941b32e9..4261873cc8e6e 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Controller\Adminhtml\Product; +use Magento\Framework\Exception\LocalizedException; + /** * @magentoAppArea adminhtml * @magentoDbIsolation enabled @@ -224,6 +226,109 @@ public function testSaveActionCleanAttributeLabelCache() $this->assertEquals('new string translation', $this->_translate('string to translate')); } + /** + * Get attribute data preset. + * + * @return array + */ + private function getLargeOptionsSetAttributeData() + { + return [ + 'frontend_label' => [ + 0 => 'testdrop1', + 1 => '', + 2 => '', + ], + 'frontend_input' => 'select', + 'is_required' => '0', + 'update_product_preview_image' => '0', + 'use_product_image_for_swatch' => '0', + 'visual_swatch_validation' => '', + 'visual_swatch_validation_unique' => '', + 'text_swatch_validation' => '', + 'text_swatch_validation_unique' => '', + 'attribute_code' => 'test_many_options', + 'is_global' => '0', + 'default_value_text' => '', + 'default_value_yesno' => '0', + 'default_value_date' => '', + 'default_value_textarea' => '', + 'is_unique' => '0', + 'is_used_in_grid' => '1', + 'is_visible_in_grid' => '1', + 'is_filterable_in_grid' => '1', + 'is_searchable' => '0', + 'is_comparable' => '0', + 'is_filterable' => '0', + 'is_filterable_in_search' => '0', + 'is_used_for_promo_rules' => '0', + 'is_html_allowed_on_front' => '1', + 'is_visible_on_front' => '0', + 'used_in_product_listing' => '0', + 'used_for_sort_by' => '0', + 'swatch_input_type' => 'dropdown', + ]; + } + + /** + * Test attribute saving with large amount of options exceeding maximum allowed by max_input_vars limit. + * @return void + */ + public function testLargeOptionsDataSet() + { + $maxInputVars = ini_get('max_input_vars'); + // Each option is at least 4 variables array (order, admin value, first store view value, delete flag). + // Set options count to exceed max_input_vars by 100 options (400 variables). + $optionsCount = floor($maxInputVars / 4) + 100; + $attributeData = $this->getLargeOptionsSetAttributeData(); + $optionsData = []; + $expectedOptionsLabels = []; + for ($i = 0; $i < $optionsCount; $i++) { + $order = $i + 1; + $expectedOptionLabelOnStoreView = "value_{$i}_store_1"; + $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; + $optionsData []= "option[order][option_{$i}]={$order}"; + $optionsData []= "option[value][option_{$i}][0]=value_{$i}_admin"; + $optionsData []= "option[value][option_{$i}][1]={$expectedOptionLabelOnStoreView}"; + $optionsData []= "option[delete][option_{$i}="; + } + $attributeData['serialized_options'] = json_encode($optionsData); + $this->getRequest()->setPostValue($attributeData); + $this->dispatch('backend/catalog/product_attribute/save'); + $entityTypeId = $this->_objectManager->create( + \Magento\Eav\Model\Entity::class + )->setType( + \Magento\Catalog\Model\Product::ENTITY + )->getTypeId(); + + /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ + $attribute = $this->_objectManager->create( + \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class + )->setEntityTypeId( + $entityTypeId + ); + try { + $attribute->loadByCode($entityTypeId, 'test_many_options'); + $options = $attribute->getOptions(); + // assert that all options are saved without truncation + $this->assertEquals( + $optionsCount + 1, + count($options), + 'Expected options count does not match (regarding first empty option for non-required attribute)' + ); + + foreach ($expectedOptionsLabels as $optionOrderNum => $label) { + $this->assertEquals( + $label, + $options[$optionOrderNum]->getLabel(), + "Label for option #{$optionOrderNum} does not match expected." + ); + } + } catch (LocalizedException $e) { + $this->fail('Test failed with exception on attribute model load: ' . $e); + } + } + /** * Return translation for a string literal belonging to backend area * diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/_files/category_multiple_stores.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/_files/category_multiple_stores.php index 84b57f8706620..5ccace9086316 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/_files/category_multiple_stores.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/_files/category_multiple_stores.php @@ -44,11 +44,6 @@ $store->save(); } -/* Refresh stores memory cache */ -\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Store\Model\StoreManagerInterface::class -)->reinitStores(); - /** @var \Magento\Catalog\Model\Category $newCategory */ $newCategory = $factory->create(); $newCategory diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/custom_category_store_media_disabled.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/custom_category_store_media_disabled.php index c2b8dc98e4a16..e1a359fbdaa8f 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/custom_category_store_media_disabled.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/custom_category_store_media_disabled.php @@ -47,8 +47,3 @@ $objectManager->create(\Magento\Eav\Model\AttributeSetManagement::class) ->create($entityTypeCode, $attributeSet, $defaultSetId); - -/* Refresh stores memory cache */ -\Magento\TestFramework\Helper\Bootstrap::getObjectManager() - ->get(\Magento\Store\Model\StoreManagerInterface::class) - ->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/two_categories_per_two_store_groups.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/two_categories_per_two_store_groups.php index 90a74351d8200..f77413e18f472 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/two_categories_per_two_store_groups.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/two_categories_per_two_store_groups.php @@ -65,6 +65,3 @@ ->save(); $store->setGroupId($storeGroup->getId())->save(); - -/* Refresh stores memory cache */ -$objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Client/ElasticsearchTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Client/ElasticsearchTest.php index 0731871b4bd40..61add5f7d0ea7 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Client/ElasticsearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Client/ElasticsearchTest.php @@ -100,7 +100,7 @@ private function search($text) */ public function testSearchConfigurableProductBySimpleProductName() { - $this->assertProductWithSkuFound('configurable', $this->search('Configurable OptionOption')); + $this->assertProductWithSkuFound('configurable', $this->search('Configurable Option')); } /** diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php index 4cdff533af737..014aaf7679bc9 100755 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/IndexHandlerTest.php @@ -5,13 +5,18 @@ */ namespace Magento\Elasticsearch\Model\Indexer; -use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Action as ProductAction; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\CatalogInventory\Api\StockRegistryInterface; +use Magento\CatalogInventory\Api\StockItemRepositoryInterface; +use Magento\CatalogSearch\Model\Indexer\Fulltext as CatalogSearchFulltextIndexer; use Magento\TestFramework\Helper\Bootstrap; use Magento\Store\Model\StoreManagerInterface; use Magento\Elasticsearch\SearchAdapter\ConnectionManager; use Magento\Elasticsearch\Model\Client\Elasticsearch as ElasticsearchClient; use Magento\Elasticsearch\Model\Config; use Magento\Elasticsearch\SearchAdapter\SearchIndexNameResolver; +use Magento\Indexer\Model\Indexer; /** * Important: Please make sure that each integration test file works with unique elastic search index. In order to @@ -20,107 +25,79 @@ * * @magentoDbIsolation disabled * @magentoDataFixture Magento/Elasticsearch/_files/indexer.php + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class IndexHandlerTest extends \PHPUnit\Framework\TestCase { /** - * @var ConnectionManager + * @var ProductRepositoryInterface */ - protected $connectionManager; + private $productRepository; /** * @var ElasticsearchClient */ - protected $client; + private $client; /** * @var StoreManagerInterface */ - protected $storeManager; + private $storeManager; /** * @var int[] */ - protected $storeIds; + private $storeIds; /** - * @var Config + * @var string */ - protected $clientConfig; + private $entityType; /** - * @var SearchIndexNameResolver - */ - protected $searchIndexNameResolver; - - /** - * @var Product - */ - protected $productApple; - - /** - * @var Product - */ - protected $productBanana; - - /** - * @var Product - */ - protected $productOrange; - - /** - * @var Product + * @var Indexer */ - protected $productPapaya; + private $indexer; /** - * @var Product + * @var SearchIndexNameResolver */ - protected $productCherry; + private $searchIndexNameResolver; /** - * Setup method + * {@inheritdoc} */ protected function setUp() { - $this->connectionManager = Bootstrap::getObjectManager()->create( - \Magento\Elasticsearch\SearchAdapter\ConnectionManager::class - ); - - $this->client = $this->connectionManager->getConnection(); + $connectionManager = Bootstrap::getObjectManager()->create(ConnectionManager::class); + $this->client = $connectionManager->getConnection(); - $this->storeManager = Bootstrap::getObjectManager()->create( - \Magento\Store\Model\StoreManagerInterface::class - ); + $this->storeManager = Bootstrap::getObjectManager()->create(StoreManagerInterface::class); $this->storeIds = array_keys($this->storeManager->getStores()); - $this->clientConfig = Bootstrap::getObjectManager()->create( - \Magento\Elasticsearch\Model\Config::class - ); + $clientConfig = Bootstrap::getObjectManager()->create(Config::class); + $this->entityType = $clientConfig->getEntityType(); - $this->searchIndexNameResolver = Bootstrap::getObjectManager()->create( - \Magento\Elasticsearch\SearchAdapter\SearchIndexNameResolver::class - ); + $this->indexer = Bootstrap::getObjectManager()->create(Indexer::class); + $this->indexer->load(CatalogSearchFulltextIndexer::INDEXER_ID); + $this->indexer->reindexAll(); - $this->productApple = $this->getProductBySku('fulltext-1'); - $this->productBanana = $this->getProductBySku('fulltext-2'); - $this->productOrange = $this->getProductBySku('fulltext-3'); - $this->productPapaya = $this->getProductBySku('fulltext-4'); - $this->productCherry = $this->getProductBySku('fulltext-5'); + $this->searchIndexNameResolver = Bootstrap::getObjectManager()->create(SearchIndexNameResolver::class); + $this->productRepository = Bootstrap::getObjectManager()->create(ProductRepositoryInterface::class); } /** - * Test reindex process * @magentoConfigFixture default/catalog/search/engine elasticsearch * @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest + * @return void */ - public function testReindexAll() + public function testReindexAll(): void { - $this->reindexAll(); + $productApple = $this->productRepository->get('fulltext-1'); foreach ($this->storeIds as $storeId) { $products = $this->searchByName('Apple', $storeId); $this->assertCount(1, $products); - $this->assertEquals($this->productApple->getId(), $products[0]['_id']); + $this->assertEquals($productApple->getId(), $products[0]['_id']); $products = $this->searchByName('Simple Product', $storeId); $this->assertCount(5, $products); @@ -128,19 +105,17 @@ public function testReindexAll() } /** + * @magentoAppIsolation enabled * @magentoConfigFixture default/catalog/search/engine elasticsearch * @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest + * @return void */ - public function testReindexRowAfterEdit() + public function testReindexRowAfterEdit(): void { - // The test executes fine locally. On bamboo there is some issue with parallel test execution or other - // test interaction. It is being marked as skipped until more time is available to investigate and - // fix the issue. - $this->markTestSkipped('MAGETWO-53851 - Ticket to investiage this test failure on Bamboo and fix it.'); - - $this->productApple->setData('name', 'Simple Product Cucumber'); - $this->productApple->save(); - $this->reindexAll(); + $this->storeManager->setCurrentStore('admin'); + $productApple = $this->productRepository->get('fulltext-1'); + $productApple->setName('Simple Product Cucumber'); + $this->productRepository->save($productApple); foreach ($this->storeIds as $storeId) { $products = $this->searchByName('Apple', $storeId); @@ -148,7 +123,7 @@ public function testReindexRowAfterEdit() $products = $this->searchByName('Cucumber', $storeId); $this->assertCount(1, $products); - $this->assertEquals($this->productApple->getId(), $products[0]['_id']); + $this->assertEquals($productApple->getId(), $products[0]['_id']); $products = $this->searchByName('Simple Product', $storeId); $this->assertCount(5, $products); @@ -158,22 +133,21 @@ public function testReindexRowAfterEdit() /** * @magentoConfigFixture default/catalog/search/engine elasticsearch * @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest + * @return void */ - public function testReindexRowAfterMassAction() + public function testReindexRowAfterMassAction(): void { - $this->reindexAll(); + $productApple = $this->productRepository->get('fulltext-1'); + $productBanana = $this->productRepository->get('fulltext-2'); $productIds = [ - $this->productApple->getId(), - $this->productBanana->getId(), + $productApple->getId(), + $productBanana->getId(), ]; $attrData = [ 'name' => 'Simple Product Common', ]; - - /** @var \Magento\Catalog\Model\Product\Action $action */ - $action = Bootstrap::getObjectManager()->get( - \Magento\Catalog\Model\Product\Action::class - ); + /** @var ProductAction $action */ + $action = Bootstrap::getObjectManager()->get(ProductAction::class); foreach ($this->storeIds as $storeId) { $action->updateAttributes($productIds, $attrData, $storeId); @@ -199,30 +173,67 @@ public function testReindexRowAfterMassAction() * @magentoConfigFixture default/catalog/search/engine elasticsearch * @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest * @magentoAppArea adminhtml + * @return void */ - public function testReindexRowAfterDelete() + public function testReindexRowAfterDelete(): void { - $this->reindexAll(); - $this->productBanana->delete(); + $productBanana = $this->productRepository->get('fulltext-2'); + $this->productRepository->delete($productBanana); foreach ($this->storeIds as $storeId) { + $products = $this->searchByName('Banana', $storeId); + $this->assertEmpty($products); + $products = $this->searchByName('Simple Product', $storeId); $this->assertCount(4, $products); } } /** - * Search docs in Elasticsearch by name + * @magentoDbIsolation enabled + * @magentoAppArea adminhtml + * @magentoConfigFixture default/catalog/search/engine elasticsearch + * @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest + * @magentoDataFixture Magento/Elasticsearch/_files/configurable_products.php + * @return void + */ + public function testReindexRowAfterUpdateStockStatus(): void + { + foreach ($this->storeIds as $storeId) { + $products = $this->searchByName('ProductOption1', $storeId); + $this->assertNotEmpty($products); + } + $product = $this->productRepository->get('simple_10'); + /** @var StockRegistryInterface $stockRegistry */ + $stockRegistry = Bootstrap::getObjectManager()->create(StockRegistryInterface::class); + $stockItem = $stockRegistry->getStockItem($product->getId()); + $stockItem->setIsInStock(false); + /** @var StockItemRepositoryInterface $stockRepository */ + $stockRepository = Bootstrap::getObjectManager()->create(StockItemRepositoryInterface::class); + $stockRepository->save($stockItem); + + foreach ($this->storeIds as $storeId) { + $products = $this->searchByName('ProductOption1', $storeId); + $this->assertEmpty($products); + + $products = $this->searchByName('Configurable', $storeId); + $this->assertNotEmpty($products); + } + } + + /** + * Search docs in Elasticsearch by name. * * @param string $text * @param int $storeId * @return array */ - protected function searchByName($text, $storeId) + private function searchByName(string $text, int $storeId): array { + $index = $this->searchIndexNameResolver->getIndexName($storeId, $this->indexer->getId()); $searchQuery = [ - 'index' => $this->searchIndexNameResolver->getIndexName($storeId, 'catalogsearch_fulltext'), - 'type' => $this->clientConfig->getEntityType(), + 'index' => $index, + 'type' => $this->entityType, 'body' => [ 'query' => [ 'bool' => [ @@ -240,35 +251,7 @@ protected function searchByName($text, $storeId) ]; $queryResult = $this->client->query($searchQuery); $products = isset($queryResult['hits']['hits']) ? $queryResult['hits']['hits'] : []; - return $products; - } - - /** - * Return product by SKU - * - * @param string $sku - * @return Product - */ - protected function getProductBySku($sku) - { - /** @var Product $product */ - $product = Bootstrap::getObjectManager()->get( - \Magento\Catalog\Model\Product::class - ); - return $product->loadByAttribute('sku', $sku); - } - /** - * Perform full reindex - * - * @return void - */ - private function reindexAll() - { - $indexer = Bootstrap::getObjectManager()->create( - \Magento\Indexer\Model\Indexer::class - ); - $indexer->load('catalogsearch_fulltext'); - $indexer->reindexAll(); + return $products; } } diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_attribute.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_attribute.php new file mode 100644 index 0000000000000..7ec53d9099d35 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_attribute.php @@ -0,0 +1,62 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Eav\Api\AttributeRepositoryInterface; + +$eavConfig = Bootstrap::getObjectManager()->get(\Magento\Eav\Model\Config::class); +$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable'); + +$eavConfig->clear(); + +/** @var $installer \Magento\Catalog\Setup\CategorySetup */ +$installer = Bootstrap::getObjectManager()->create(\Magento\Catalog\Setup\CategorySetup::class); + +if (!$attribute->getId()) { + /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ + $attribute = Bootstrap::getObjectManager()->create( + \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class + ); + + /** @var AttributeRepositoryInterface $attributeRepository */ + $attributeRepository = Bootstrap::getObjectManager()->create(AttributeRepositoryInterface::class); + + $attribute->setData( + [ + 'attribute_code' => 'test_configurable', + 'entity_type_id' => $installer->getEntityTypeId('catalog_product'), + 'is_global' => 1, + 'is_user_defined' => 1, + 'frontend_input' => 'select', + 'is_unique' => 0, + 'is_required' => 0, + 'is_searchable' => 0, + 'is_visible_in_advanced_search' => 0, + 'is_comparable' => 0, + 'is_filterable' => 0, + 'is_filterable_in_search' => 0, + 'is_used_for_promo_rules' => 0, + 'is_html_allowed_on_front' => 1, + 'is_visible_on_front' => 0, + 'used_in_product_listing' => 0, + 'used_for_sort_by' => 0, + 'frontend_label' => ['Test Configurable'], + 'backend_type' => 'int', + 'option' => [ + 'value' => ['option_0' => ['Option 1'], 'option_1' => ['Option 2']], + 'order' => ['option_0' => 1, 'option_1' => 2], + ], + ] + ); + + $attributeRepository->save($attribute); + + /* Assign attribute to attribute set */ + $installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId()); +} + +$eavConfig->clear(); diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_attribute_rollback.php new file mode 100644 index 0000000000000..7bdfbc6d7f9b3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_attribute_rollback.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +$eavConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Eav\Model\Config::class); +$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable'); +if ($attribute instanceof \Magento\Eav\Model\Entity\Attribute\AbstractAttribute + && $attribute->getId() +) { + $attribute->delete(); +} +$eavConfig->clear(); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_products.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_products.php index c2dd3c2f879e1..f8872b02ba246 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_products.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_products.php @@ -17,7 +17,7 @@ require __DIR__ . '/select_attribute.php'; require __DIR__ . '/multiselect_attribute.php'; -require __DIR__ . '/../../ConfigurableProduct/_files/configurable_attribute.php'; +require __DIR__ . '/configurable_attribute.php'; $objectManager = Bootstrap::getObjectManager(); @@ -45,7 +45,7 @@ ->setId($productId) ->setAttributeSetId($attributeSetId) ->setWebsiteIds([1]) - ->setName('Configurable Option' . $option->getLabel()) + ->setName('Configurable Option Product' . str_replace(' ', '', $option->getLabel())) ->setSku('simple_' . $productId) ->setPrice($productId) ->setTestConfigurable($option->getValue()) diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_products_rollback.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_products_rollback.php index 0d062c9d3f4e4..e73d2ab1b5906 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_products_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/configurable_products_rollback.php @@ -25,7 +25,7 @@ } } -require __DIR__ . '/../../ConfigurableProduct/_files/configurable_attribute_rollback.php'; +require __DIR__ . '/configurable_attribute_rollback.php'; require __DIR__ . '/select_attribute_rollback.php'; require __DIR__ . '/multiselect_attribute_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer.php index 8ee3a40915028..cf87be7e8d710 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer.php @@ -31,9 +31,6 @@ \Magento\Store\Model\ScopeInterface::SCOPE_STORES, $store->getId() ); - - /* Refresh stores memory cache */ - $storeManager->reinitStores(); } /** @var $productFirst \Magento\Catalog\Model\Product */ @@ -52,7 +49,7 @@ ->setStockData(['use_config_manage_stock' => 0]) ->save(); -/** @var $productFirst \Magento\Catalog\Model\Product */ +/** @var $productSecond \Magento\Catalog\Model\Product */ $productSecond = $objectManager->create(\Magento\Catalog\Model\Product::class); $productSecond->setTypeId('simple') ->setAttributeSetId(4) @@ -68,7 +65,7 @@ ->setStockData(['use_config_manage_stock' => 0]) ->save(); -/** @var $productFirst \Magento\Catalog\Model\Product */ +/** @var $productThird \Magento\Catalog\Model\Product */ $productThird = $objectManager->create(\Magento\Catalog\Model\Product::class); $productThird->setTypeId('simple') ->setAttributeSetId(4) @@ -84,7 +81,7 @@ ->setStockData(['use_config_manage_stock' => 0]) ->save(); -/** @var $productFirst \Magento\Catalog\Model\Product */ +/** @var $productFourth \Magento\Catalog\Model\Product */ $productFourth = $objectManager->create(\Magento\Catalog\Model\Product::class); $productFourth->setTypeId('simple') ->setAttributeSetId(4) @@ -100,7 +97,7 @@ ->setStockData(['use_config_manage_stock' => 0]) ->save(); -/** @var $productFirst \Magento\Catalog\Model\Product */ +/** @var $productFifth \Magento\Catalog\Model\Product */ $productFifth = $objectManager->create(\Magento\Catalog\Model\Product::class); $productFifth->setTypeId('simple') ->setAttributeSetId(4) diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer_rollback.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer_rollback.php index 1d5f1161f3d58..9ca4f78660b3a 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/indexer_rollback.php @@ -29,6 +29,3 @@ $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); - -/* Refresh stores memory cache */ -$objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/requests.xml b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/requests.xml index c40ac9e8b9b1c..0aaaf9b85857f 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/requests.xml +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/_files/requests.xml @@ -394,13 +394,18 @@ <queries> <query xsi:type="boolQuery" name="filter_out_of_stock_child" boost="1"> <queryReference clause="must" ref="test_configurable"/> + <queryReference clause="must" ref="visibility"/> </query> <query xsi:type="filteredQuery" name="test_configurable"> <filterReference clause="must" ref="test_configurable_filter"/> </query> + <query xsi:type="filteredQuery" name="visibility"> + <filterReference clause="must" ref="visibility_filter"/> + </query> </queries> <filters> <filter xsi:type="termFilter" name="test_configurable_filter" field="test_configurable" value="$test_configurable$"/> + <filter xsi:type="termFilter" name="visibility_filter" field="visibility" value="$visibility$"/> </filters> <aggregations/> <from>0</from> diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php index 581630e9626fa..ecbce25cd3377 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php @@ -63,6 +63,10 @@ protected function setUp() ); $this->adapter = $this->createAdapter(); + + $indexer = $this->objectManager->create(\Magento\Indexer\Model\Indexer::class); + $indexer->load('catalogsearch_fulltext'); + $indexer->reindexAll(); } /** @@ -531,9 +535,15 @@ public function testAdvancedSearchCompositeProductWithOutOfStockOption() ->create(Collection::class) ->setAttributeFilter($attribute->getId()); + $visibility = [ + \Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_SEARCH, + \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH, + ]; + $firstOption = $selectOptions->getFirstItem(); $firstOptionId = $firstOption->getId(); $this->requestBuilder->bind('test_configurable', $firstOptionId); + $this->requestBuilder->bind('visibility', $visibility); $this->requestBuilder->setRequestName('filter_out_of_stock_child'); $queryResponse = $this->executeQuery(); @@ -542,6 +552,7 @@ public function testAdvancedSearchCompositeProductWithOutOfStockOption() $secondOption = $selectOptions->getLastItem(); $secondOptionId = $secondOption->getId(); $this->requestBuilder->bind('test_configurable', $secondOptionId); + $this->requestBuilder->bind('visibility', $visibility); $this->requestBuilder->setRequestName('filter_out_of_stock_child'); $queryResponse = $this->executeQuery(); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable.php index 2f30cba3d8ee6..8a7c5246f373a 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable.php @@ -15,8 +15,6 @@ use Magento\Eav\Api\Data\AttributeOptionInterface; use Magento\TestFramework\Helper\Bootstrap; -Bootstrap::getInstance()->reinitialize(); - require __DIR__ . '/configurable_attribute.php'; /** @var ProductRepositoryInterface $productRepository */ diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml index 70f9ac75b07f3..dcf3cd582507c 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml @@ -394,13 +394,18 @@ <queries> <query xsi:type="boolQuery" name="filter_out_of_stock_child" boost="1"> <queryReference clause="must" ref="test_configurable"/> + <queryReference clause="must" ref="visibility"/> </query> <query xsi:type="filteredQuery" name="test_configurable"> <filterReference clause="must" ref="test_configurable_filter"/> </query> + <query xsi:type="filteredQuery" name="visibility"> + <filterReference clause="must" ref="visibility_filter"/> + </query> </queries> <filters> <filter xsi:type="termFilter" name="test_configurable_filter" field="test_configurable" value="$test_configurable$"/> + <filter xsi:type="termFilter" name="visibility_filter" field="visibility" value="$visibility$"/> </filters> <aggregations/> <from>0</from> diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_weight_products.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_weight_products.php index b672fbe9f8cec..3902e78d1fb55 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_weight_products.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/search_weight_products.php @@ -7,18 +7,8 @@ */ use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\Attribute\Source\Status; -use Magento\Catalog\Model\Product\Type; -use Magento\Catalog\Model\Product\Visibility; -use Magento\Catalog\Setup\CategorySetup; -use Magento\ConfigurableProduct\Helper\Product\Options\Factory; -use Magento\ConfigurableProduct\Model\Product\Type\Configurable; -use Magento\Eav\Api\Data\AttributeOptionInterface; use Magento\TestFramework\Helper\Bootstrap; -Bootstrap::getInstance()->reinitialize(); - $objectManager = Bootstrap::getObjectManager(); /** @var ProductRepositoryInterface $productRepository */ diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/expected/styles.magento.min.css b/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/expected/styles.magento.min.css index 99c21441f9dbc..7bb283e0b3514 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/expected/styles.magento.min.css +++ b/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/expected/styles.magento.min.css @@ -1 +1 @@ -table>caption{margin-bottom:5px}table thead{background:#676056;color:#f7f3eb}table thead .headings{background:#807a6e}table thead a{color:#f7f3eb;display:block}table thead a label{color:#f7f3eb;cursor:pointer;display:block}table thead a:hover,table thead a:focus{color:#dac7a2;text-decoration:none}table tfoot{background:#f2ebde;color:#676056}table tfoot tr th,table tfoot tr td{text-align:left}table th{background:0 0;border:solid #cac3b4;border-width:0 1px;font-size:14px;padding:6px 10px;text-align:center}table td{border:solid #cac3b4;border-width:0 1px;padding:6px 10px 7px;vertical-align:top}table tbody tr td{background:#fff;color:#676056;padding-top:12px}table tbody tr td:first-child{border-left:0}table tbody tr td:first-child input[type=checkbox]{margin:0}table tbody tr td:last-child{border-right:0}table tbody tr:last-child th,table tbody tr:last-child td{border-bottom-width:1px}table tbody tr:nth-child(odd) td,table tbody tr:nth-child(odd) th{background-color:#f7f3eb}table tbody.even tr td{background:#fff}table tbody.odd tr td{background:#f7f3eb}table .dropdown-menu li{padding:7px 15px;line-height:14px;cursor:pointer}table .col-draggable .draggable-handle{float:left;position:relative;top:0}.not-sort{padding-right:10px}.sort-arrow-asc,.sort-arrow-desc{padding-right:10px;position:relative}.sort-arrow-asc:after,.sort-arrow-desc:after{right:-11px;top:-1px;position:absolute;width:23px}.sort-arrow-asc:hover:after,.sort-arrow-desc:hover:after{color:#dac7a2}.sort-arrow-asc{display:inline-block;text-decoration:none}.sort-arrow-asc:after{font-family:'icons-blank-theme';content:'\e626';font-size:13px;line-height:inherit;color:#f7f3eb;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.sort-arrow-asc:hover:after{color:#dac7a2}.sort-arrow-desc{display:inline-block;text-decoration:none}.sort-arrow-desc:after{font-family:'icons-blank-theme';content:'\e623';font-size:13px;line-height:inherit;color:#f7f3eb;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.sort-arrow-desc:hover:after{color:#dac7a2}.grid-actions .input-text,.pager .input-text,.massaction .input-text,.filter .input-text,.grid-actions select,.pager select,.massaction select,.filter select,.grid-actions .select,.pager .select,.massaction .select,.filter .select{border-color:#989287;box-shadow:none;border-radius:1px;height:28px;margin:0 10px 0 0}.filter th{border:0 solid #676056;padding:6px 3px;vertical-align:top}.filter .ui-datepicker-trigger{cursor:pointer;margin-top:2px}.filter .input-text{padding:0 5px}.filter .range-line:not(:last-child){margin-bottom:5px}.filter .date{padding-right:28px;position:relative;display:inline-block;text-decoration:none}.filter .date .hasDatepicker{vertical-align:top;width:99%}.filter .date img{cursor:pointer;height:25px;width:25px;right:0;position:absolute;vertical-align:middle;z-index:2;opacity:0}.filter .date:before{font-family:'icons-blank-theme';content:'\e612';font-size:42px;line-height:30px;color:#f7f3eb;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.filter .date:hover:before{color:#dac7a2}.filter .date:before{height:29px;margin-left:5px;position:absolute;right:-3px;top:-3px;width:35px}.filter select{border-color:#cac3b4;margin:0;padding:0;width:99%}.filter input.input-text{border-color:#cac3b4;margin:0;width:99%}.filter input.input-text::-webkit-input-placeholder{color:#989287 !important;text-transform:lowercase}.filter input.input-text::-moz-placeholder{color:#989287 !important;text-transform:lowercase}.filter input.input-text:-moz-placeholder{color:#989287 !important;text-transform:lowercase}.filter input.input-text:-ms-input-placeholder{color:#989287 !important;text-transform:lowercase}.grid{background:#fff;color:#676056;font-size:13px;font-weight:400;padding:15px}.grid table{width:100%}.grid tbody tr.selected th,.grid tbody tr.selected td,.grid tbody tr:hover th,.grid tbody tr:hover td,.grid tbody tr:nth-child(odd):hover th,.grid tbody tr:nth-child(odd):hover td{background-color:#f2ebde;cursor:pointer}.grid tbody tr.selected th.empty-text,.grid tbody tr.selected td.empty-text,.grid tbody tr:hover th.empty-text,.grid tbody tr:hover td.empty-text,.grid tbody tr:nth-child(odd):hover th.empty-text,.grid tbody tr:nth-child(odd):hover td.empty-text{background-color:#f7f3eb;cursor:default}.grid .empty-text{font:400 20px/1.2 'Open Sans',sans-serif;text-align:center;white-space:nowrap}.grid .col-sku{max-width:100px;width:100px}.grid .col-select,.grid .col-massaction{text-align:center}.grid .editable .input-text{width:65px}.grid .col-actions .action-select{background:#fff;border-color:#989287;height:28px;margin:0;padding:4px 4px 5px;width:80px}.grid .col-position.editable{white-space:nowrap}.grid .col-position.editable .input-text{margin:-7px 5px 0;width:70%}.eq-ie9 .hor-scroll{display:inline-block;min-height:0;overflow-y:hidden;overflow-x:auto;width:100%}.data-table{border-collapse:separate;width:100%}.data-table thead,.data-table tfoot,.data-table th,.accordion .config .data-table thead th,.accordion .config .data-table tfoot td,.accordion .config .accordion .config .data-table tfoot td th{background:#fff;color:#676056;font-size:13px;font-weight:600}.data-table th{text-align:left}.data-table thead th,.accordion .config .data-table thead th th,.accordion .config .data-table tfoot td th,.accordion .config .accordion .config .data-table tfoot td th th{border:solid #c9c2b8;border-width:0 0 1px;padding:7px}.data-table td,.data-table tbody tr th,.data-table tbody tr td,.accordion .config .data-table td{background:#fff;border-width:0;padding:5px 7px;vertical-align:middle}.data-table tbody tr:nth-child(odd) th,.data-table tbody tr:nth-child(odd) td,.accordion .config .data-table tbody tr:nth-child(odd) td{background:#fbfaf6}.data-table tbody.odd tr th,.data-table tbody.odd tr td{background:#fbfaf6}.data-table tbody.even tr th,.data-table tbody.even tr td{background:#fff}.data-table tfoot tr:last-child th,.data-table tfoot tr:last-child td,.data-table .accordion .config .data-table tfoot tr:last-child td{border:0}.data-table.order-tables tbody td{vertical-align:top}.data-table.order-tables tbody:hover tr th,.data-table.order-tables tbody:hover tr td{background:#f7f3eb}.data-table.order-tables tfoot td{background:#f2ebde;color:#676056;font-size:13px;font-weight:600}.data-table input[type=text]{width:98%;padding-left:1%;padding-right:1%}.data-table select{margin:0;box-sizing:border-box}.data-table .col-actions .actions-split{margin-top:4px}.data-table .col-actions .actions-split [class^=action-]{background:0 0;border:1px solid #c8c3b5;padding:3px 5px;color:#bbb3a6;font-size:12px}.data-table .col-actions .actions-split [class^=action-]:first-child{border-right:0}.data-table .col-actions .actions-split .dropdown-menu{margin-top:-1px}.data-table .col-actions .actions-split .dropdown-menu a{display:block;color:#333;text-decoration:none}.data-table .col-actions .actions-split.active .action-toggle{position:relative;border-bottom-right-radius:0;box-shadow:none;background:#fff}.data-table .col-actions .actions-split.active .action-toggle:after{position:absolute;top:100%;left:0;right:0;height:2px;margin-top:-1px;background:#fff;content:'';z-index:2}.data-table .col-actions .actions-split.active .action-toggle .dropdown-menu{border-top-right-radius:0}.data-table .col-default{white-space:nowrap;text-align:center;vertical-align:middle}.data-table .col-delete{text-align:center;width:32px}.data-table .col-file{white-space:nowrap}.data-table .col-file input,.data-table .col-file .input-text{margin:0 5px;width:40%}.data-table .col-file input:first-child,.data-table .col-file .input-text:first-child{margin-left:0}.data-table .col-actions-add{padding:10px 0}.grid-actions{background:#fff;font-size:13px;line-height:28px;padding:10px 15px;position:relative}.grid-actions+.grid{padding-top:5px}.grid-actions .export,.grid-actions .filter-actions{float:right;margin-left:10px;vertical-align:top}.grid-actions .import{display:block;vertical-align:top}.grid-actions .action-reset{background:0 0;border:0;display:inline;line-height:1.42857143;margin:0;padding:0;color:#1979c3;text-decoration:none;margin:6px 10px 0 0;vertical-align:top}.grid-actions .action-reset:visited{color:purple;text-decoration:none}.grid-actions .action-reset:hover{color:#006bb4;text-decoration:underline}.grid-actions .action-reset:active{color:#ff5501;text-decoration:underline}.grid-actions .action-reset:hover{color:#006bb4}.grid-actions .action-reset:hover,.grid-actions .action-reset:active,.grid-actions .action-reset:focus{background:0 0;border:0}.grid-actions .action-reset.disabled,.grid-actions .action-reset[disabled],fieldset[disabled] .grid-actions .action-reset{color:#1979c3;text-decoration:underline;cursor:default;pointer-events:none;opacity:.5}.grid-actions .import .label,.grid-actions .export .label,.massaction>.entry-edit .label{margin:0 14px 0 0;vertical-align:inherit}.grid-actions .import .action-,.grid-actions .export .action-,.grid-actions .filter-actions .action-,.massaction>.entry-edit .action-{vertical-align:inherit}.grid-actions .filter .date{float:left;margin:0 15px 0 0;position:relative}.grid-actions .filter .date:before{color:#676056;top:1px}.grid-actions .filter .date:hover:before{color:#31302b}.grid-actions .filter .label{margin:0}.grid-actions .filter .hasDatepicker{margin:0 5px;width:80px}.grid-actions .filter .show-by .select{margin-left:5px;padding:4px 4px 5px;vertical-align:top;width:auto}.grid-actions .filter.required:after{content:''}.grid-actions img{vertical-align:middle;height:22px;width:22px}.grid-actions .validation-advice{background:#f9d4d4;border:1px solid #e22626;border-radius:3px;color:#e22626;margin:5px 0 0;padding:3px 7px;position:absolute;white-space:nowrap;z-index:5}.grid-actions .validation-advice:before{width:0;height:0;border:5px solid transparent;border-bottom-color:#e22626;content:'';left:50%;margin-left:-5px;position:absolute;top:-11px}.grid-actions input[type=text].validation-failed{border-color:#e22626;box-shadow:0 0 8px rgba(226,38,38,.6)}.grid-actions .link-feed{white-space:nowrap}.pager{font-size:13px}.grid .pager{margin:15px 0 0;position:relative;text-align:center}.pager .pages-total-found{margin-right:25px}.pager .view-pages .select{margin:0 5px}.pager .link-feed{font-size:12px;margin:7px 15px 0 0;position:absolute;right:0;top:0}.pager .action-previous,.pager .action-next{background:0 0;border:0;display:inline;line-height:1.42857143;margin:0;padding:0;color:#1979c3;text-decoration:none;line-height:.6;overflow:hidden;width:20px}.pager .action-previous:visited,.pager .action-next:visited{color:purple;text-decoration:none}.pager .action-previous:hover,.pager .action-next:hover{color:#006bb4;text-decoration:underline}.pager .action-previous:active,.pager .action-next:active{color:#ff5501;text-decoration:underline}.pager .action-previous:hover,.pager .action-next:hover{color:#006bb4}.pager .action-previous:hover,.pager .action-next:hover,.pager .action-previous:active,.pager .action-next:active,.pager .action-previous:focus,.pager .action-next:focus{background:0 0;border:0}.pager .action-previous.disabled,.pager .action-next.disabled,.pager .action-previous[disabled],.pager .action-next[disabled],fieldset[disabled] .pager .action-previous,fieldset[disabled] .pager .action-next{color:#1979c3;text-decoration:underline;cursor:default;pointer-events:none;opacity:.5}.pager .action-previous:before,.pager .action-next:before{margin-left:-10px}.pager .action-previous.disabled,.pager .action-next.disabled{opacity:.3}.pager .action-previous{display:inline-block;text-decoration:none}.pager .action-previous>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.pager .action-previous>span.focusable:active,.pager .action-previous>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.pager .action-previous>span.focusable:active,.pager .action-previous>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.pager .action-previous:before{font-family:'icons-blank-theme';content:'\e617';font-size:40px;line-height:inherit;color:#026294;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.pager .action-previous:hover:before{color:#007dbd}.pager .action-next{display:inline-block;text-decoration:none}.pager .action-next>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.pager .action-next>span.focusable:active,.pager .action-next>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.pager .action-next>span.focusable:active,.pager .action-next>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.pager .action-next:before{font-family:'icons-blank-theme';content:'\e608';font-size:40px;line-height:inherit;color:#026294;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.pager .action-next:hover:before{color:#007dbd}.pager .input-text{height:25px;line-height:16px;margin-right:5px;text-align:center;width:25px;vertical-align:top}.pager .pages-total{line-height:25px;vertical-align:top}.massaction{background:#fff;border-top:1px solid #f2ebde;font-size:13px;line-height:28px;padding:15px 15px 0}.massaction>.entry-edit{float:right}.massaction>.entry-edit .field-row{display:inline-block;vertical-align:top}.massaction>.entry-edit .validation-advice{display:none !important}.massaction>.entry-edit .form-inline{display:inline-block}.massaction>.entry-edit .label{padding:0;width:auto}.massaction>.entry-edit .action-{vertical-align:top}.massaction .select.validation-failed{border:1px dashed #e22626;background:#f9d4d4}.grid-severity-critical,.grid-severity-major,.grid-severity-notice,.grid-severity-minor{background:#feeee1;border:1px solid #ed4f2e;color:#ed4f2e;display:block;padding:0 3px;font-weight:700;line-height:17px;text-transform:uppercase;text-align:center}.grid-severity-critical,.grid-severity-major{border-color:#e22626;background:#f9d4d4;color:#e22626}.grid-severity-notice{border-color:#5b8116;background:#d0e5a9;color:#185b00}.grid tbody td input[type=text],.data-table tbody td input[type=text],.grid tbody th input[type=text],.data-table tbody th input[type=text],.grid tbody td .input-text,.data-table tbody td .input-text,.grid tbody th .input-text,.data-table tbody th .input-text,.grid tbody td select,.data-table tbody td select,.grid tbody th select,.data-table tbody th select,.grid tbody td .select,.data-table tbody td .select,.grid tbody th .select,.data-table tbody th .select{width:99%}.ui-tabs-panel .grid .col-sku{max-width:150px;width:150px}.col-indexer_status,.col-indexer_mode{width:160px}.fieldset-wrapper .grid-actions+.grid{padding-top:15px}.fieldset-wrapper .grid-actions{padding:10px 0 0}.fieldset-wrapper .grid{padding:0}.fieldset-wrapper .massaction{padding:0;border-top:none;margin-bottom:15px}.accordion .grid{padding:0}.ui-dialog-content .grid-actions,.ui-dialog-content .grid{padding-left:0;padding-right:0}.qty-table td{border:0;padding:0 5px 3px}.sales-order-create-index .sales-order-create-index .grid table .action-configure{float:right}.sales-order-create-index .data-table .border td{padding-bottom:15px}.sales-order-create-index .actions.update{margin:10px 0}.adminhtml-order-shipment-new .grid .col-product{max-width:770px;width:770px}.customer-index-index .grid .col-name{max-width:90px;width:90px}.customer-index-index .grid .col-billing_region{width:70px}.adminhtml-cms-hierarchy-index .col-title,.adminhtml-cms-hierarchy-index .col-identifier{max-width:410px;width:410px}.adminhtml-widget-instance-edit .grid-chooser .control{margin-top:-19px;width:80%}.eq-ie9 .adminhtml-widget-instance-edit .grid-chooser .control{margin-top:-18px}.adminhtml-widget-instance-edit .grid-chooser .control .grid-actions{padding:0 0 15px}.adminhtml-widget-instance-edit .grid-chooser .control .grid{padding:0}.adminhtml-widget-instance-edit .grid-chooser .control .addon input:last-child,.adminhtml-widget-instance-edit .grid-chooser .control .addon select:last-child{border-radius:0}.reports-report-product-sold .grid .col-name{max-width:720px;width:720px}.adminhtml-system-store-index .grid td{max-width:310px}.adminhtml-system-currency-index .grid{padding-top:0}.adminhtml-system-currency-index .col-currency-edit-rate{min-width:40px}.adminhtml-system-currency-index .col-base-currency{font-weight:700}.adminhtml-system-currency-index .old-rate{display:block;margin-top:3px;text-align:center}.adminhtml-system-currency-index .hor-scroll{overflow-x:auto;min-width:970px}.adminhtml-system-currencysymbol-index .col-currency{width:35%}.adminhtml-system-currencysymbol-index .grid .input-text{margin:0 10px 0 0;width:50%}.catalog-product-set-index .col-set_name{max-width:930px;width:930px}.adminhtml-export-index .grid td{vertical-align:middle}.adminhtml-export-index .grid .input-text-range{margin:0 10px 0 5px;width:37%}.adminhtml-export-index .grid .input-text-range-date{margin:0 5px;width:32%}.adminhtml-export-index .ui-datepicker-trigger{display:inline-block;margin:-3px 10px 0 0;vertical-align:middle}.adminhtml-notification-index .grid .col-select,.adminhtml-cache-index .grid .col-select,.adminhtml-process-list .grid .col-select,.indexer-indexer-list .grid .col-select{width:10px}@font-face{font-family:'icons-blank-theme';src:url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot');src:url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot?#iefix') format('embedded-opentype'),url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2') format('woff2'),url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff') format('woff'),url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.ttf') format('truetype'),url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.svg#icons-blank-theme') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'icons-blank-theme';src:url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot');src:url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot?#iefix') format('embedded-opentype'),url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2') format('woff2'),url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff') format('woff'),url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.ttf') format('truetype');font-weight:400;font-style:normal}.navigation{background-color:#676056;position:relative;z-index:5}.navigation .level-0.reverse>.submenu{right:1px}.navigation>ul{position:relative;text-align:right}.navigation .level-0>.submenu{display:none;position:absolute;top:100%;padding:19px 13px}.navigation .level-0>.submenu a{display:block;color:#676056;font-size:13px;font-weight:400;line-height:1.385;padding:3px 12px 3px;text-decoration:none}.navigation .level-0>.submenu a:focus,.navigation .level-0>.submenu a:hover{text-decoration:underline}.navigation .level-0>.submenu a:hover{color:#fff;background:#989287;text-decoration:none}.navigation .level-0>.submenu li{margin-bottom:1px}.navigation .level-0>.submenu a[href="#"]{cursor:default;display:block;color:#676056;font-size:14px;font-weight:700;line-height:1;margin:7px 0 6px;padding:0 12px}.navigation .level-0>.submenu a[href="#"]:focus,.navigation .level-0>.submenu a[href="#"]:hover{color:#676056;font-size:14px;font-weight:700;background:0 0;text-decoration:none}.navigation .level-0{display:inline-block;float:left;text-align:left;transition:display .15s ease-out}.navigation .level-0>a{background:0 0;display:block;padding:12px 13px 0;color:#f2ebde;font-size:13px;font-weight:600;text-transform:uppercase;text-decoration:none;transition:background .15s ease-out}.navigation .level-0>a:after{content:"";display:block;margin-top:10px;height:3px;font-size:0}.navigation .level-0.active>a{font-weight:700}.navigation .level-0.active>a:after{background:#ef672f}.navigation .level-0.hover.recent>a{background:#fff;color:#676056;font-size:13px;font-weight:600}.navigation .level-0.hover.recent>a:after{background:0 0}.navigation .level-0.hover.recent.active>a{font-weight:700}.navigation .level-0>.submenu{opacity:0;visibility:hidden}.navigation .level-0.recent.hover>.submenu{opacity:1;visibility:visible}.no-js .navigation .level-0:hover>.submenu,.no-js .navigation .level-0.hover>.submenu,.no-js .navigation .level-0>a:focus+.submenu{display:block}.navigation .level-0>.submenu{background:#fff;box-shadow:0 3px 3px rgba(50,50,50,.15)}.navigation .level-0>.submenu li{max-width:200px}.navigation .level-0>.submenu>ul{white-space:nowrap}.navigation .level-0>.submenu .column{display:inline-block;margin-left:40px;vertical-align:top}.navigation .level-0>.submenu .column:first-child{margin-left:0}.navigation .level-0 .submenu .level-1{white-space:normal}.navigation .level-0.parent .submenu .level-1.parent{margin:17px 0 25px}.navigation .level-0.parent .level-1.parent:first-child{margin-top:0}.navigation .level-2 .submenu{margin-left:7px}.navigation .level-0>.submenu .level-2>a[href="#"]{font-size:13px;margin-top:10px;margin-left:7px}.navigation .level-2>.submenu a{font-size:12px;line-height:1.231}.navigation .level-0>.submenu .level-3>a[href="#"],.navigation .level-3 .submenu{margin-left:15px}.navigation .level-0.item-system,.navigation .level-0.item-stores{float:none}.navigation .level-0.item-system>.submenu,.navigation .level-0.item-stores>.submenu{left:auto;right:1px}.adminhtml-dashboard-index .col-1-layout{max-width:1300px;border:none;border-radius:0;padding:0;background:#f7f3eb}.dashboard-inner{padding-top:35px}.dashboard-inner:before,.dashboard-inner:after{content:"";display:table}.dashboard-inner:after{clear:both}.dashboard-inner:before,.dashboard-inner:after{content:"";display:table}.dashboard-inner:after{clear:both}.dashboard-secondary{float:left;width:32%;margin:0 1.5%}.dashboard-main{float:right;width:65%}.dashboard-diagram-chart{max-width:100%;height:auto}.dashboard-diagram-nodata,.dashboard-diagram-switcher{padding:20px 0}.dashboard-diagram-image{background:#fff url(../mui/images/ajax-loader-small.gif) no-repeat 50% 50%}.dashboard-container .ui-tabs-panel{background-color:#fff;min-height:40px;padding:15px}.dashboard-store-stats{margin-top:35px}.dashboard-store-stats .ui-tabs-panel{background:#fff url(../mui/images/ajax-loader-small.gif) no-repeat 50% 50%}.dashboard-item{margin-bottom:30px}.dashboard-item-header{margin-left:5px}.dashboard-item.dashboard-item-primary{margin-bottom:35px}.dashboard-item.dashboard-item-primary .title{font-size:22px;margin-bottom:5px}.dashboard-item.dashboard-item-primary .dashboard-sales-value{display:block;text-align:right;font-weight:600;font-size:30px;margin-right:12px;padding-bottom:5px}.dashboard-item.dashboard-item-primary:first-child{color:#ef672f}.dashboard-item.dashboard-item-primary:first-child .title{color:#ef672f}.dashboard-totals{background:#fff;padding:50px 15px 25px}.dashboard-totals-list{margin:0;padding:0;list-style:none none}.dashboard-totals-list:before,.dashboard-totals-list:after{content:"";display:table}.dashboard-totals-list:after{clear:both}.dashboard-totals-list:before,.dashboard-totals-list:after{content:"";display:table}.dashboard-totals-list:after{clear:both}.dashboard-totals-item{float:left;width:18%;margin-left:7%;padding-top:15px;border-top:2px solid #cac3b4}.dashboard-totals-item:first-child{margin-left:0}.dashboard-totals-label{display:block;font-size:16px;font-weight:600;padding-bottom:2px}.dashboard-totals-value{color:#ef672f;font-size:20px}.dashboard-data{width:100%}.dashboard-data thead{background:0 0}.dashboard-data thead tr{background:0 0}.dashboard-data th,.dashboard-data td{border:none;padding:10px 12px;text-align:right}.dashboard-data th:first-child,.dashboard-data td:first-child{text-align:left}.dashboard-data th{color:#676056;font-weight:600}.dashboard-data td{background-color:transparent}.dashboard-data tbody tr:hover td{background-color:transparent}.dashboard-data tbody tr:nth-child(odd) td,.dashboard-data tbody tr:nth-child(odd):hover td,.dashboard-data tbody tr:nth-child(odd) th,.dashboard-data tbody tr:nth-child(odd):hover th{background-color:#e1dbcf}.ui-tabs-panel .dashboard-data tbody tr:nth-child(odd) td,.ui-tabs-panel .dashboard-data tbody tr:nth-child(odd):hover td,.ui-tabs-panel .dashboard-data tbody tr:nth-child(odd) th,.ui-tabs-panel .dashboard-data tbody tr:nth-child(odd):hover th{background-color:#f7f3eb}.dashboard-data td.empty-text{text-align:center}.ui-tabs-panel .dashboard-data{background-color:#fff}.mage-dropdown-dialog.ui-dialog .ui-dialog-content{overflow:visible}.mage-dropdown-dialog.ui-dialog .ui-dialog-buttonpane{padding:0}.message-system-inner{background:#f7f3eb;border:1px solid #c0bbaf;border-top:0;border-radius:0 0 5px 5px;float:right;overflow:hidden}.message-system-unread .message-system-inner{float:none}.message-system-list{margin:0;padding:0;list-style:none;float:left}.message-system .message-system-list{width:75%}.message-system-list li{padding:5px 13px 7px 36px;position:relative}.message-system-short{padding:5px 13px 7px;float:right}.message-system-short span{display:inline-block;margin-left:7px;border-left:1px #d1ccc3 solid}.message-system-short span:first-child{border:0;margin-left:0}.message-system-short a{padding-left:27px;position:relative;height:16px}.message-system .message-system-short a:before,.message-system-list li:before{font-family:'MUI-Icons';font-style:normal;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;height:16px;width:16px;font-size:16px;line-height:16px;text-align:center;position:absolute;left:7px;top:2px}.message-system-list li:before{top:5px;left:13px}.message-system .message-system-short .warning a:before,.message-system-list li.warning:before{content:"\e006";color:#f2a825}.message-system .message-system-short .error a:before,.message-system-list li.error:before{content:"\e086";font-family:'MUI-Icons';color:#c00815}.ui-dialog .message-system-list{margin-bottom:25px}.sales-order-create-index .order-errors .notice{color:#ed4f2e;font-size:11px;margin:5px 0 0}.order-errors .fieldset-wrapper-title .title{box-sizing:border-box;background:#fffbf0;border:1px solid #d87e34;border-radius:5px;color:#676056;font-size:14px;margin:20px 0;padding:10px 26px 10px 35px;position:relative}.order-errors .fieldset-wrapper-title .title:before{position:absolute;left:11px;top:50%;margin-top:-11px;width:auto;height:auto;font-family:'MUI-Icons';font-style:normal;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;font-size:16px;line-height:inherit;content:'\e046';color:#d87e34}.search-global.miniform{position:relative;z-index:1000;display:inline-block;vertical-align:top;margin:6px 10px 0}.search-global.miniform .mage-suggest{border:0;border-radius:0}.search-global-actions{display:none}.search-global-field{margin:0}.search-global-field .label{position:absolute;right:4px;z-index:2;cursor:pointer;display:inline-block;text-decoration:none}.search-global-field .label>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.search-global-field .label>span.focusable:active,.search-global-field .label>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.search-global-field .label>span.focusable:active,.search-global-field .label>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.search-global-field .label:before{font-family:'MUI-Icons';content:"\e01f";font-size:18px;line-height:29px;color:#cac3b4;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.search-global-field .control{width:48px;overflow:hidden;opacity:0;transition:all .3s ease}.search-global-field .control input[type=text]{background:0 0;border:none;width:100%}.search-global-field.active{z-index:2}.search-global-field.active .label:before{display:none}.search-global-field.active .control{overflow:visible;opacity:1;transition:all .3s ease;width:300px}.search-global-menu{box-sizing:border-box;display:block;width:100%}.notifications-summary{display:inline-block;text-align:left;position:relative;z-index:1}.notifications-summary.active{z-index:999}.notifications-action{color:#f2ebde;padding:12px 22px 11px;text-transform:capitalize;display:inline-block;text-decoration:none}.notifications-action:before{font-family:"MUI-Icons";content:"\e06e";font-size:18px;line-height:18px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.notifications-action:visited,.notifications-action:focus,.notifications-action:active,.notifications-action:hover{color:#f2ebde;text-decoration:none}.notifications-action.active{background-color:#fff;color:#676056}.notifications-action .text{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.notifications-action .text.focusable:active,.notifications-action .text.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-action .text.focusable:active,.notifications-action .text.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-action .qty.counter{display:inline-block;background:#ed4f2e;color:#f2ebde;font-size:12px;line-height:12px;font-weight:700;padding:1px 3px;position:absolute;top:6px;left:50%;border-radius:4px}.notifications-list{width:300px;padding:0;margin:0}.notifications-list .last{padding:10px;text-align:center;font-size:12px}.notifications-summary .notifications-entry{padding:15px;color:#676056;font-size:11px;font-weight:400}.notifications-entry{position:relative;z-index:1}.notifications-entry:hover .action{display:block}.notifications-entry-title{padding-right:15px;color:#ed4f2e;font-size:12px;font-weight:600;display:block;margin-bottom:10px}.notifications-entry-description{line-height:1.3;display:block;max-height:3.9em;overflow:hidden;margin-bottom:10px;text-overflow:ellipsis}.notifications-close.action{position:absolute;z-index:1;top:12px;right:12px;display:inline-block;background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400;display:none}.notifications-close.action>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.notifications-close.action>span.focusable:active,.notifications-close.action>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-close.action>span.focusable:active,.notifications-close.action>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-close.action:before{font-family:'MUI-Icons';content:"\e07f";font-size:16px;line-height:inherit;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.notifications-close.action:focus,.notifications-close.action:active{background:0 0;border:none}.notifications-close.action:hover{background:0 0;border:none}.notifications-close.action.disabled,.notifications-close.action[disabled],fieldset[disabled] .notifications-close.action{cursor:not-allowed;pointer-events:none;opacity:.5}.notifications-dialog-content{display:none}.notifications-critical .notifications-entry-title{padding-left:25px;display:inline-block;text-decoration:none}.notifications-critical .notifications-entry-title:before{font-family:'MUI-Icons';content:"\e086";font-size:18px;line-height:18px;color:#c00815;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.notifications-critical .notifications-entry-title:before{position:absolute;margin-left:-25px}.notifications-dialog-content .notifications-entry-time{color:#8c867e;font-size:13px;font-family:Helvetica,Arial,sans-serif;position:absolute;right:17px;bottom:27px;text-align:right}.notifications-url{display:inline-block;text-decoration:none}.notifications-url>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.notifications-url>span.focusable:active,.notifications-url>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-url>span.focusable:active,.notifications-url>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-url:after{font-family:'MUI-Icons';content:"\e084";font-size:16px;line-height:inherit;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center;margin:-2px 0 0 10px}.notifications-dialog-content .notifications-entry-title{font-size:15px}.locale-switcher-field{white-space:nowrap;float:left}.locale-switcher-field .control,.locale-switcher-field .label{vertical-align:middle;margin:0 10px 0 0;display:inline-block}.locale-switcher-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;border:1px solid #ada89e;max-width:200px;height:31px;background:url("../images/select-bg.svg") no-repeat 100% 50%;background-size:30px 60px;padding-right:29px;text-indent:.01px;text-overflow:''}.locale-switcher-select::-ms-expand{display:none}.lt-ie10 .locale-switcher-select{background-image:none;padding-right:4px}@-moz-document url-prefix(){.locale-switcher-select{background-image:none}}@-moz-document url-prefix(){.locale-switcher-select{background-image:none}}.mage-suggest{text-align:left;box-sizing:border-box;position:relative;display:inline-block;vertical-align:top;width:100%;background-color:#fff;border:1px solid #ada89e;border-radius:2px}.mage-suggest:after{position:absolute;top:3px;right:3px;bottom:0;width:22px;text-align:center;font-family:'MUI-Icons';font-style:normal;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;content:'\e01f';font-size:18px;color:#b2b2b2}.mage-suggest input[type=search],.mage-suggest input.search{width:100%;border:none;background:0 0;padding-right:30px}.mage-suggest.category-select input[type=search],.mage-suggest.category-select input.search{height:26px}.mage-suggest-dropdown{position:absolute;left:0;right:0;top:100%;margin:1px -1px 0;border:1px solid #cac2b5;background:#fff;box-shadow:0 2px 4px rgba(0,0,0,.2);z-index:990}.mage-suggest-dropdown ul{margin:0;padding:0;list-style:none}.mage-suggest-dropdown li{border-bottom:1px solid #e5e5e5;padding:0}.mage-suggest-dropdown li a{display:block}.mage-suggest-dropdown li a.ui-state-focus{background:#f5f5f5}.mage-suggest-dropdown li a,.mage-suggest-dropdown .jstree li a:hover,.mage-suggest-dropdown .jstree .jstree-hovered,.mage-suggest-dropdown .jstree .jstree-clicked{padding:6px 12px 5px;text-decoration:none;color:#333}.mage-suggest-dropdown .jstree li a:hover,.mage-suggest-dropdown .jstree .jstree-hovered,.mage-suggest-dropdown .jstree .jstree-clicked{border:none}.mage-suggest-dropdown .jstree li{border-bottom:0}.mage-suggest-dropdown .jstree li a{display:inline-block}.mage-suggest-dropdown .jstree .mage-suggest-selected>a{color:#000;background:#f1ffeb}.field-category_ids .mage-suggest-dropdown,.field-new_category_parent .mage-suggest-dropdown{max-height:200px;overflow:auto}.mage-suggest-dropdown .jstree .mage-suggest-selected>a:hover,.mage-suggest-dropdown .jstree .mage-suggest-selected>.jstree-hovered,.mage-suggest-dropdown .jstree .mage-suggest-selected>.jstree-clicked,.mage-suggest-dropdown .jstree .mage-suggest-selected.mage-suggest-not-active>.jstree-hovered,.mage-suggest-dropdown .jstree .mage-suggest-selected.mage-suggest-not-active>.jstree-clicked{background:#e5ffd9}.mage-suggest-dropdown .jstree .mage-suggest-not-active>a{color:#d4d4d4}.mage-suggest-dropdown .jstree .mage-suggest-not-active>a:hover,.mage-suggest-dropdown .jstree .mage-suggest-not-active>.jstree-hovered,.mage-suggest-dropdown .jstree .mage-suggest-not-active>.jstree-clicked{background:#f5f5f5}.mage-suggest-dropdown .category-path{font-size:11px;margin-left:10px;color:#9ba8b5}.suggest-expandable .action-dropdown .action-toggle{display:inline-block;max-width:500px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:0 0;border:none;box-shadow:none;color:#676056;font-size:12px;padding:5px 4px;filter:none}.suggest-expandable .action-dropdown .action-toggle span{display:inline}.suggest-expandable .action-dropdown .action-toggle:before{display:inline-block;float:right;margin-left:4px;font-size:13px;color:#b2b0ad}.suggest-expandable .action-dropdown .action-toggle:hover:before{color:#7e7e7e}.suggest-expandable .dropdown-menu{margin:1px 0 0;left:0;right:auto;width:245px;z-index:4}.suggest-expandable .mage-suggest{border:none;border-radius:3px 3px 0 0}.suggest-expandable .mage-suggest:after{top:10px;right:8px}.suggest-expandable .mage-suggest-inner .title{margin:0;padding:0 10px 4px;text-transform:uppercase;color:#a6a098;font-size:12px;border-bottom:1px solid #e5e5e5}.suggest-expandable .mage-suggest-inner>input[type=search],.suggest-expandable .mage-suggest-inner>input.search{position:relative;margin:6px 5px 5px;padding-right:20px;border:1px solid #ada89e;width:236px;z-index:1}.suggest-expandable .mage-suggest-inner>input.ui-autocomplete-loading,.suggest-expandable .mage-suggest-inner>input.mage-suggest-state-loading{background:#fff url("../mui/images/ajax-loader-small.gif") no-repeat 190px 50%}.suggest-expandable .mage-suggest-dropdown{margin-top:0;border-top:0;border-radius:0 0 3px 3px;max-height:300px;overflow:auto;width:100%;float:left}.suggest-expandable .mage-suggest-dropdown ul{margin:0;padding:0;list-style:none}.suggest-expandable .action-show-all:hover,.suggest-expandable .action-show-all:active,.suggest-expandable .action-show-all:focus,.suggest-expandable .action-show-all[disabled]{border-top:1px solid #e5e5e5;display:block;width:100%;padding:8px 10px 10px;text-align:left;font:12px/1.333 Arial,Verdana,sans-serif;color:#676056}.product-actions .suggest-expandable{max-width:500px;float:left;margin-top:1px}.page-actions.fixed #product-template-suggest-container{display:none}.catalog-category-edit .col-2-left-layout:before{display:none}.category-content .ui-tabs-panel .fieldset{padding-top:40px}.category-content .ui-tabs-panel .fieldset .legend{display:none}.attributes-edit-form .field:not(.field-weight) .addon{display:block;position:relative}.attributes-edit-form .field:not(.field-weight) .addon input[type=text]{border-width:1px}.attributes-edit-form .field:not(.field-weight) .addon .addafter{display:block;border:0;height:auto;width:auto}.attributes-edit-form .field:not(.field-weight) .addon input:focus~.addafter{box-shadow:none}.attributes-edit-form .with-addon .textarea{margin:0}.attributes-edit-form .attribute-change-checkbox{display:block;margin-top:5px}.attributes-edit-form .attribute-change-checkbox .label{float:none;padding:0;width:auto}.attributes-edit-form .attribute-change-checkbox .checkbox{margin-right:5px;width:auto}.attributes-edit-form .field-price .addon>input,.attributes-edit-form .field-special_price .addon>input,.attributes-edit-form .field-gift_wrapping_price .addon>input,.attributes-edit-form .field-msrp .addon>input,.attributes-edit-form .field-gift_wrapping_price .addon>input{padding-left:23px}.attributes-edit-form .field-price .addafter>strong,.attributes-edit-form .field-special_price .addafter>strong,.attributes-edit-form .field-gift_wrapping_price .addafter>strong,.attributes-edit-form .field-msrp .addafter>strong,.attributes-edit-form .field-gift_wrapping_price .addafter>strong{left:5px;position:absolute;top:3px}.attributes-edit-form .field.type-price input:focus+label,.attributes-edit-form .field-price input:focus+label,.attributes-edit-form .field-special_price input:focus+label,.attributes-edit-form .field-msrp input:focus+label,.attributes-edit-form .field-weight input:focus+label{box-shadow:none}.attributes-edit-form .field-special_from_date>.control .input-text,.attributes-edit-form .field-special_to_date>.control .input-text,.attributes-edit-form .field-news_from_date>.control .input-text,.attributes-edit-form .field-news_to_date>.control .input-text,.attributes-edit-form .field-custom_design_from>.control .input-text,.attributes-edit-form .field-custom_design_to>.control .input-text{border-width:1px;width:130px}.attributes-edit-form .field-weight .fields-group-2 .control{padding-right:27px}.attributes-edit-form .field-weight .fields-group-2 .control .addafter+.addafter{border-width:1px 1px 1px 0;border-style:solid;height:28px;right:0;position:absolute;top:0}.attributes-edit-form .field-weight .fields-group-2 .control .addafter strong{line-height:28px}.attributes-edit-form .field-weight .fields-group-2 .control>input:focus+.addafter+.addafter{box-shadow:0 0 8px rgba(82,168,236,.6)}.attributes-edit-form .field-gift_message_available .addon>input[type=checkbox],.attributes-edit-form .field-gift_wrapping_available .addon>input[type=checkbox]{width:auto;margin-right:5px}.attributes-edit-form .fieldset>.addafter{display:none}.advanced-inventory-edit .field.choice{display:block;margin:3px 0 0}.advanced-inventory-edit .field.choice .label{padding-top:1px}.product-actions:before,.product-actions:after{content:"";display:table}.product-actions:after{clear:both}.product-actions:before,.product-actions:after{content:"";display:table}.product-actions:after{clear:both}.product-actions .switcher{float:right}#configurable-attributes-container .actions-select{display:inline-block;position:relative}#configurable-attributes-container .actions-select:before,#configurable-attributes-container .actions-select:after{content:"";display:table}#configurable-attributes-container .actions-select:after{clear:both}#configurable-attributes-container .actions-select:before,#configurable-attributes-container .actions-select:after{content:"";display:table}#configurable-attributes-container .actions-select:after{clear:both}#configurable-attributes-container .actions-select .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}#configurable-attributes-container .actions-select .action.toggle:after{font-family:'icons-blank-theme';content:'\e607';font-size:22px;line-height:22px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}#configurable-attributes-container .actions-select .action.toggle:hover:after{color:inherit}#configurable-attributes-container .actions-select .action.toggle:active:after{color:inherit}#configurable-attributes-container .actions-select .action.toggle.active{display:inline-block;text-decoration:none}#configurable-attributes-container .actions-select .action.toggle.active:after{font-family:'icons-blank-theme';content:'\e618';font-size:22px;line-height:22px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}#configurable-attributes-container .actions-select .action.toggle.active:hover:after{color:inherit}#configurable-attributes-container .actions-select .action.toggle.active:active:after{color:inherit}#configurable-attributes-container .actions-select ul.dropdown{margin:0;padding:0;list-style:none none;box-sizing:border-box;background:#fff;border:1px solid #bbb;position:absolute;z-index:100;top:100%;min-width:100%;margin-top:4px;display:none;box-shadow:0 3px 3px rgba(0,0,0,.15)}#configurable-attributes-container .actions-select ul.dropdown li{margin:0;padding:3px 5px}#configurable-attributes-container .actions-select ul.dropdown li:hover{background:#e8e8e8;cursor:pointer}#configurable-attributes-container .actions-select.active{overflow:visible}#configurable-attributes-container .actions-select.active ul.dropdown{display:block}#configurable-attributes-container .actions-select .action.toggle{padding:1px 8px;border:1px solid #ada89e;background:#fff;border-radius:0 2px 2px 0}#configurable-attributes-container .actions-select .action.toggle:after{width:14px;text-indent:-2px}#configurable-attributes-container .actions-select ul.dropdown li:hover{background:#eef8fc}#configurable-attributes-container .actions-select ul.dropdown a{color:#333;text-decoration:none}#product-variations-matrix .actions-image-uploader{display:inline-block;position:relative;display:block;width:50px}#product-variations-matrix .actions-image-uploader:before,#product-variations-matrix .actions-image-uploader:after{content:"";display:table}#product-variations-matrix .actions-image-uploader:after{clear:both}#product-variations-matrix .actions-image-uploader:before,#product-variations-matrix .actions-image-uploader:after{content:"";display:table}#product-variations-matrix .actions-image-uploader:after{clear:both}#product-variations-matrix .actions-image-uploader .action.split{float:left;margin:0}#product-variations-matrix .actions-image-uploader .action.toggle{float:right;margin:0}#product-variations-matrix .actions-image-uploader .action.toggle{padding:6px 5px;display:inline-block;text-decoration:none}#product-variations-matrix .actions-image-uploader .action.toggle>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}#product-variations-matrix .actions-image-uploader .action.toggle>span.focusable:active,#product-variations-matrix .actions-image-uploader .action.toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}#product-variations-matrix .actions-image-uploader .action.toggle>span.focusable:active,#product-variations-matrix .actions-image-uploader .action.toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}#product-variations-matrix .actions-image-uploader .action.toggle:after{font-family:'icons-blank-theme';content:'\e607';font-size:22px;line-height:14px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}#product-variations-matrix .actions-image-uploader .action.toggle:hover:after{color:inherit}#product-variations-matrix .actions-image-uploader .action.toggle:active:after{color:inherit}#product-variations-matrix .actions-image-uploader .action.toggle.active{display:inline-block;text-decoration:none}#product-variations-matrix .actions-image-uploader .action.toggle.active>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}#product-variations-matrix .actions-image-uploader .action.toggle.active>span.focusable:active,#product-variations-matrix .actions-image-uploader .action.toggle.active>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}#product-variations-matrix .actions-image-uploader .action.toggle.active>span.focusable:active,#product-variations-matrix .actions-image-uploader .action.toggle.active>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}#product-variations-matrix .actions-image-uploader .action.toggle.active:after{font-family:'icons-blank-theme';content:'\e618';font-size:22px;line-height:14px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}#product-variations-matrix .actions-image-uploader .action.toggle.active:hover:after{color:inherit}#product-variations-matrix .actions-image-uploader .action.toggle.active:active:after{color:inherit}#product-variations-matrix .actions-image-uploader ul.dropdown{margin:0;padding:0;list-style:none none;box-sizing:border-box;background:#fff;border:1px solid #bbb;position:absolute;z-index:100;top:100%;min-width:100%;margin-top:4px;display:none;box-shadow:0 3px 3px rgba(0,0,0,.15)}#product-variations-matrix .actions-image-uploader ul.dropdown li{margin:0;padding:3px 5px}#product-variations-matrix .actions-image-uploader ul.dropdown li:hover{background:#e8e8e8;cursor:pointer}#product-variations-matrix .actions-image-uploader.active{overflow:visible}#product-variations-matrix .actions-image-uploader.active ul.dropdown{display:block}#product-variations-matrix .actions-image-uploader .action.toggle{padding:0 2px;border:1px solid #b7b2a7;background:#fff;border-radius:0 4px 4px 0;border-left:none;height:33px}#product-variations-matrix .actions-image-uploader .action.toggle.no-display{display:none}#product-variations-matrix .actions-image-uploader .action.toggle:after{width:12px;text-indent:-5px}#product-variations-matrix .actions-image-uploader ul.dropdown{left:0;margin-left:0;width:100px}#product-variations-matrix .actions-image-uploader ul.dropdown li:hover{background:#eef8fc}#product-variations-matrix .actions-image-uploader ul.dropdown a{color:#333;text-decoration:none}.debugging-hints .page-actions{position:relative;z-index:1}.debugging-hints .page-actions .debugging-hint-template-file{left:auto !important;right:0 !important}.filter-segments{list-style:none;padding:0}.adminhtml-report-customer-test-detail .col-id{width:35px}.adminhtml-report-customer-test-detail .col-period{white-space:nowrap;width:70px}.adminhtml-report-customer-test-detail .col-zip{width:50px}.adminhtml-report-customer-test-segment .col-id{width:35px}.adminhtml-report-customer-test-segment .col-status{width:65px}.adminhtml-report-customer-test-segment .col-qty{width:145px}.adminhtml-report-customer-test-segment .col-segment,.adminhtml-report-customer-test-segment .col-website{width:35%}.adminhtml-report-customer-test-segment .col-select{width:45px}.test-custom-attributes{margin-bottom:20px}.adminhtml-test-index th.col-id{text-align:left}.adminhtml-test-index .col-price{text-align:right;width:50px}.adminhtml-test-index .col-actions{width:50px}.adminhtml-test-index .col-select{width:60px}.adminhtml-test-edit .field-image .control{line-height:28px}.adminhtml-test-edit .field-image a{display:inline-block;margin:0 5px 0 0}.adminhtml-test-edit .field-image img{vertical-align:middle}.adminhtml-test-new .field-image .input-file,.adminhtml-test-edit .field-image .input-file{display:inline-block;margin:0 15px 0 0;width:auto}.adminhtml-test-new .field-image .addafter,.adminhtml-test-edit .field-image .addafter{border:0;box-shadow:none;display:inline-block;margin:0 15px 0 0;height:auto;width:auto}.adminhtml-test-new .field-image .delete-image,.adminhtml-test-edit .field-image .delete-image{display:inline-block;white-space:nowrap}.adminhtml-test-edit .field-image .delete-image input{margin:-3px 5px 0 0;width:auto;display:inline-block}.adminhtml-test-edit .field-image .addon .delete-image input:focus+label{border:0;box-shadow:none}.adminhtml-test-index .col-id{width:35px}.adminhtml-test-index .col-status{white-space:normal;width:75px}.adminhtml-test-index .col-websites{white-space:nowrap;width:200px}.adminhtml-test-index .col-price .label{display:inline-block;min-width:60px;white-space:nowrap}.adminhtml-test-index .col-price .price-excl-tax .price,.adminhtml-test-index .col-price .price-incl-tax .price{font-weight:700}.invitee_information,.inviter_information{width:48.9362%}.invitee_information{float:left}.inviter_information{float:right}.test_information .data-table th,.invitee_information .data-table th,.inviter_information .data-table th{width:20%;white-space:nowrap}.test_information .data-table textarea,.test_information .data-table input{width:100%}.tests-history ul{margin:0;padding-left:25px}.tests-history ul .status:before{display:inline-block;content:"|";margin:0 10px}.adminhtml-report-test-order .col-period{white-space:nowrap;width:70px}.adminhtml-report-test-order .col-inv-sent,.adminhtml-report-test-order .col-inv-acc,.adminhtml-report-test-order .col-acc,.adminhtml-report-test-order .col-rate{text-align:right;width:23%}.adminhtml-report-test-customer .col-id{width:35px}.adminhtml-report-test-customer .col-period{white-space:nowrap;width:70px}.adminhtml-report-test-customer .col-inv-sent,.adminhtml-report-test-customer .col-inv-acc{text-align:right;width:120px}.adminhtml-report-test-index .col-period{white-space:nowrap}.adminhtml-report-test-index .col-inv-sent,.adminhtml-report-test-index .col-inv-acc,.adminhtml-report-test-index .col-inv-disc,.adminhtml-report-test-index .col-inv-acc-rate,.adminhtml-report-test-index .col-inv-disc-rate{text-align:right;width:19%}.test_information .data-table,.invitee_information .data-table,.inviter_information .data-table{width:100%}.test_information .data-table tbody tr th,.invitee_information .data-table tbody tr th,.inviter_information .data-table tbody tr th{font-weight:700}.test_information .data-table tbody tr td,.test_information .data-table tbody tr th,.invitee_information .data-table tbody tr td,.invitee_information .data-table tbody tr th,.inviter_information .data-table tbody tr td,.inviter_information .data-table tbody tr th{background-color:#fff;border:0;padding:9px 10px 10px;color:#666;vertical-align:top}.test_information .data-table tbody tr:nth-child(2n+1) td,.test_information .data-table tbody tr:nth-child(2n+1) th,.invitee_information .data-table tbody tr:nth-child(2n+1) td,.invitee_information .data-table tbody tr:nth-child(2n+1) th,.inviter_information .data-table tbody tr:nth-child(2n+1) td,.inviter_information .data-table tbody tr:nth-child(2n+1) th{background-color:#fbfaf6}[class^=" adminhtml-test-"] .fieldset-wrapper-content .data-table .col-sort-order{width:80px}[class^=" adminhtml-test-"] .fieldset-wrapper-content .data-table td,[class^=" adminhtml-test-"] .fieldset-wrapper-content .accordion .config .data-table td{vertical-align:top}[class^=" adminhtml-test-"] .fieldset-wrapper-content .data-table td select,[class^=" adminhtml-test-"] .fieldset-wrapper-content .accordion .config .data-table td select{display:block;width:100%}[class^=" adminhtml-test-"] .fieldset-wrapper-content .data-table td .input-radio.global-scope,[class^=" adminhtml-test-"] .fieldset-wrapper-content .accordion .config .data-table td .input-radio.global-scope{margin-top:9px}.sales-order-create-index .ui-dialog .content>.test .field.text .input-text{width:100%}.sales-order-create-index .ui-dialog .content>.test .note .price{font-weight:600}.sales-order-create-index .ui-dialog .content>.test .note .price:before{content:": "}.sales-order-create-index .ui-dialog .content>.test .fixed.amount .label:after{content:": "}.sales-order-create-index .ui-dialog .content>.test .fixed.amount .control{display:inline-block;font-weight:600}.sales-order-create-index .ui-dialog .content>.test .fixed.amount .control .control-value{margin:-2px 0 0;padding:0}.eq-ie9 [class^=" adminhtml-test-"] .custom-options .data-table{word-wrap:normal;table-layout:auto}.rma-items .col-actions a.disabled,.newRma .col-actions a.disabled{cursor:default;opacity:.5}.rma-items .col-actions a.disabled:hover,.newRma .col-actions a.disabled:hover{text-decoration:none}.block.mselect-list .mselect-input{width:100%}.block.mselect-list .mselect-input-container .mselect-save{top:4px}.block.mselect-list .mselect-input-container .mselect-cancel{top:4px}html{font-size:62.5%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;font-size-adjust:100%}body,html{height:100%;min-height:100%}body{color:#676056;font-family:'Open Sans',sans-serif;line-height:1.33;font-weight:400;font-size:1.4rem;background:#f2ebde;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}body>*{-webkit-flex-grow:0;flex-grow:0;-webkit-flex-shrink:0;flex-shrink:0;-webkit-flex-basis:auto;flex-basis:auto}.page-wrapper{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;min-height:100%;width:100%;max-width:100%;min-width:990px}.page-wrapper>*{-webkit-flex-grow:0;flex-grow:0;-webkit-flex-shrink:0;flex-shrink:0;-webkit-flex-basis:auto;flex-basis:auto}.page-header{text-align:right}.page-header-wrapper{background-color:#31302b}.page-header:after{content:"";display:table;clear:both}.page-header .logo{margin-top:5px;float:left;text-decoration:none;display:inline-block}.page-header .logo:before{content:"";display:inline-block;vertical-align:middle;width:109px;height:35px;background-image:url("../images/logo.svg");background-size:109px 70px;background-repeat:no-repeat}.page-header .logo:after{display:inline-block;vertical-align:middle;margin-left:10px;content:attr(data-edition);font-weight:600;font-size:16px;color:#ef672f;margin-top:-2px}.page-header .logo span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.page-header .logo span.focusable:active,.page-header .logo span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.page-header .logo span.focusable:active,.page-header .logo span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.page-header .dropdown-menu{border:0}.admin-user{display:inline-block;vertical-align:top;position:relative;text-align:left}.admin-user-account{text-decoration:none;display:inline-block;padding:12px 14px;color:#f2ebde}.admin-user-account:after{font-family:"MUI-Icons";content:"\e02c";font-size:13px;line-height:13px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center;margin:-3px 0 0}.admin-user-account:link,.admin-user-account:visited{color:#f2ebde}.admin-user-account:focus,.admin-user-account:active,.admin-user-account:hover{color:#f2ebde;text-decoration:none}.active .admin-user-account{background-color:#fff;color:#676056}.admin-user-menu{padding:15px;white-space:nowrap;margin-top:0}.admin-user-menu li{border:0;padding:0}.admin-user-menu li:hover{background:0 0}.admin-user-menu a{display:block;color:#676056;font-size:13px;font-weight:400;line-height:1.385;padding:3px 12px 3px;text-decoration:none}.admin-user-menu a:focus,.admin-user-menu a:hover{text-decoration:underline}.admin-user-menu a:hover{color:#fff;background:#989287;text-decoration:none}.admin-user-menu a span:before{content:"("}.admin-user-menu a span:after{content:")"}.page-actions.fixed .page-actions-buttons{padding-right:15px}.page-main-actions{background:#e0dace;color:#645d53;padding:15px;margin-left:auto;margin-right:auto;box-sizing:border-box}.page-main-actions:before,.page-main-actions:after{content:"";display:table}.page-main-actions:after{clear:both}.page-main-actions:before,.page-main-actions:after{content:"";display:table}.page-main-actions:after{clear:both}.page-main-actions .page-actions{float:right}.page-main-actions .page-actions .page-actions-buttons{float:right;display:-webkit-flex;display:-ms-flexbox;display:flex;justify-content:flex-end}.page-main-actions .page-actions button,.page-main-actions .page-actions .action-add.mselect-button-add{margin-left:13px}.page-main-actions .page-actions button.primary,.page-main-actions .page-actions .action-add.mselect-button-add.primary{float:right;-ms-flex-order:2;-webkit-order:2;order:2}.page-main-actions .page-actions button.save:not(.primary),.page-main-actions .page-actions .action-add.mselect-button-add.save:not(.primary){float:right;-ms-flex-order:1;-webkit-order:1;order:1}.page-main-actions .page-actions button.back,.page-main-actions .page-actions button.action-back,.page-main-actions .page-actions button.delete,.page-main-actions .page-actions .action-add.mselect-button-add.back,.page-main-actions .page-actions .action-add.mselect-button-add.action-back,.page-main-actions .page-actions .action-add.mselect-button-add.delete{background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400;margin:0 13px}.page-main-actions .page-actions button.back:focus,.page-main-actions .page-actions button.action-back:focus,.page-main-actions .page-actions button.delete:focus,.page-main-actions .page-actions button.back:active,.page-main-actions .page-actions button.action-back:active,.page-main-actions .page-actions button.delete:active,.page-main-actions .page-actions .action-add.mselect-button-add.back:focus,.page-main-actions .page-actions .action-add.mselect-button-add.action-back:focus,.page-main-actions .page-actions .action-add.mselect-button-add.delete:focus,.page-main-actions .page-actions .action-add.mselect-button-add.back:active,.page-main-actions .page-actions .action-add.mselect-button-add.action-back:active,.page-main-actions .page-actions .action-add.mselect-button-add.delete:active{background:0 0;border:none}.page-main-actions .page-actions button.back:hover,.page-main-actions .page-actions button.action-back:hover,.page-main-actions .page-actions button.delete:hover,.page-main-actions .page-actions .action-add.mselect-button-add.back:hover,.page-main-actions .page-actions .action-add.mselect-button-add.action-back:hover,.page-main-actions .page-actions .action-add.mselect-button-add.delete:hover{background:0 0;border:none}.page-main-actions .page-actions button.back.disabled,.page-main-actions .page-actions button.action-back.disabled,.page-main-actions .page-actions button.delete.disabled,.page-main-actions .page-actions button.back[disabled],.page-main-actions .page-actions button.action-back[disabled],.page-main-actions .page-actions button.delete[disabled],fieldset[disabled] .page-main-actions .page-actions button.back,fieldset[disabled] .page-main-actions .page-actions button.action-back,fieldset[disabled] .page-main-actions .page-actions button.delete,.page-main-actions .page-actions .action-add.mselect-button-add.back.disabled,.page-main-actions .page-actions .action-add.mselect-button-add.action-back.disabled,.page-main-actions .page-actions .action-add.mselect-button-add.delete.disabled,.page-main-actions .page-actions .action-add.mselect-button-add.back[disabled],.page-main-actions .page-actions .action-add.mselect-button-add.action-back[disabled],.page-main-actions .page-actions .action-add.mselect-button-add.delete[disabled],fieldset[disabled] .page-main-actions .page-actions .action-add.mselect-button-add.back,fieldset[disabled] .page-main-actions .page-actions .action-add.mselect-button-add.action-back,fieldset[disabled] .page-main-actions .page-actions .action-add.mselect-button-add.delete{cursor:not-allowed;pointer-events:none;opacity:.5}.ie .page-main-actions .page-actions button.back,.ie .page-main-actions .page-actions button.action-back,.ie .page-main-actions .page-actions button.delete,.ie .page-main-actions .page-actions .action-add.mselect-button-add.back,.ie .page-main-actions .page-actions .action-add.mselect-button-add.action-back,.ie .page-main-actions .page-actions .action-add.mselect-button-add.delete{margin-top:6px}.page-main-actions .page-actions button.delete,.page-main-actions .page-actions .action-add.mselect-button-add.delete{color:#e22626;float:left;-ms-flex-order:-1;-webkit-order:-1;order:-1}.page-main-actions .page-actions button.back,.page-main-actions .page-actions button.action-back,.page-main-actions .page-actions .action-add.mselect-button-add.back,.page-main-actions .page-actions .action-add.mselect-button-add.action-back{float:left;-ms-flex-order:-1;-webkit-order:-1;order:-1;display:inline-block;text-decoration:none}.page-main-actions .page-actions button.back:before,.page-main-actions .page-actions button.action-back:before,.page-main-actions .page-actions .action-add.mselect-button-add.back:before,.page-main-actions .page-actions .action-add.mselect-button-add.action-back:before{font-family:'icons-blank-theme';content:'\e625';font-size:inherit;line-height:normal;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center;margin:0 2px 0 0}.page-main-actions .page-actions .actions-split{margin-left:13px;float:right;-ms-flex-order:2;-webkit-order:2;order:2}.page-main-actions .page-actions .actions-split button.primary,.page-main-actions .page-actions .actions-split .action-add.mselect-button-add.primary{float:left}.page-main-actions .page-actions .actions-split .dropdown-menu{text-align:left}.page-main-actions .page-actions .actions-split .dropdown-menu .item{display:block}.page-main-actions .page-actions.fixed{position:fixed;top:0;left:0;right:0;z-index:10;padding:0;background:-webkit-linear-gradient(top,#f5f2ed 0%,#f5f2ed 56%,rgba(245,242,237,0) 100%);background:-ms-linear-gradient(top,#f5f2ed 0%,#f5f2ed 56%,rgba(245,242,237,0) 100%);background:linear-gradient(to bottom,#f5f2ed 0%,#f5f2ed 56%,rgba(245,242,237,0) 100%);background:#e0dace}.page-main-actions .page-actions.fixed .page-actions-inner{position:relative;padding-top:15px;padding-bottom:15px;min-height:36px;text-align:right;box-sizing:border-box}.page-main-actions .page-actions.fixed .page-actions-inner:before,.page-main-actions .page-actions.fixed .page-actions-inner:after{content:"";display:table}.page-main-actions .page-actions.fixed .page-actions-inner:after{clear:both}.page-main-actions .page-actions.fixed .page-actions-inner:before,.page-main-actions .page-actions.fixed .page-actions-inner:after{content:"";display:table}.page-main-actions .page-actions.fixed .page-actions-inner:after{clear:both}.page-main-actions .page-actions.fixed .page-actions-inner:before{text-align:left;content:attr(data-title);float:left;font-size:20px;max-width:50%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lt-ie10 .page-main-actions .page-actions.fixed .page-actions-inner{background:#f5f2ed}.page-main-actions .store-switcher{margin-top:5px}.store-switcher{display:inline-block;font-size:13px}.store-switcher .label{margin-right:5px}.store-switcher .actions.dropdown{display:inline-block;position:relative}.store-switcher .actions.dropdown:before,.store-switcher .actions.dropdown:after{content:"";display:table}.store-switcher .actions.dropdown:after{clear:both}.store-switcher .actions.dropdown:before,.store-switcher .actions.dropdown:after{content:"";display:table}.store-switcher .actions.dropdown:after{clear:both}.store-switcher .actions.dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .actions.dropdown .action.toggle:after{font-family:'icons-blank-theme';content:'\e607';font-size:22px;line-height:20px;color:#645d53;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.store-switcher .actions.dropdown .action.toggle:hover:after{color:#645d53}.store-switcher .actions.dropdown .action.toggle:active:after{color:#645d53}.store-switcher .actions.dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .actions.dropdown .action.toggle.active:after{font-family:'icons-blank-theme';content:'\e618';font-size:22px;line-height:20px;color:#645d53;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.store-switcher .actions.dropdown .action.toggle.active:hover:after{color:#645d53}.store-switcher .actions.dropdown .action.toggle.active:active:after{color:#645d53}.store-switcher .actions.dropdown .dropdown-menu{margin:0;padding:0;list-style:none none;box-sizing:border-box;background:#fff;border:1px #ada89e solid;position:absolute;z-index:100;top:100%;min-width:195px;margin-top:4px;display:none;box-shadow:0 3px 3px rgba(0,0,0,.15)}.store-switcher .actions.dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .actions.dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .actions.dropdown.active{overflow:visible}.store-switcher .actions.dropdown.active .dropdown-menu{display:block}.store-switcher .actions.dropdown .action.toggle{background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400;color:#026294;line-height:normal;margin-top:2px;vertical-align:middle}.store-switcher .actions.dropdown .action.toggle:focus,.store-switcher .actions.dropdown .action.toggle:active{background:0 0;border:none}.store-switcher .actions.dropdown .action.toggle:hover{background:0 0;border:none}.store-switcher .actions.dropdown .action.toggle.disabled,.store-switcher .actions.dropdown .action.toggle[disabled],fieldset[disabled] .store-switcher .actions.dropdown .action.toggle{cursor:not-allowed;pointer-events:none;opacity:.5}.store-switcher .actions.dropdown ul.dropdown-menu{margin-top:4px;padding-top:5px;left:0}.store-switcher .actions.dropdown ul.dropdown-menu li{border:0;cursor:default}.store-switcher .actions.dropdown ul.dropdown-menu li:hover{cursor:default}.store-switcher .actions.dropdown ul.dropdown-menu li a,.store-switcher .actions.dropdown ul.dropdown-menu li span{padding:5px 13px;display:block;color:#645d53}.store-switcher .actions.dropdown ul.dropdown-menu li a{text-decoration:none}.store-switcher .actions.dropdown ul.dropdown-menu li a:hover{background:#edf9fb}.store-switcher .actions.dropdown ul.dropdown-menu li span{color:#ababab;cursor:default}.store-switcher .actions.dropdown ul.dropdown-menu li.current span{color:#645d53;background:#eee}.store-switcher .actions.dropdown ul.dropdown-menu .store-switcher-store a,.store-switcher .actions.dropdown ul.dropdown-menu .store-switcher-store span{padding-left:26px}.store-switcher .actions.dropdown ul.dropdown-menu .store-switcher-store-view a,.store-switcher .actions.dropdown ul.dropdown-menu .store-switcher-store-view span{padding-left:39px}.store-switcher .actions.dropdown ul.dropdown-menu .dropdown-toolbar{border-top:1px #ededed solid;margin-top:10px}.store-switcher .actions.dropdown ul.dropdown-menu .dropdown-toolbar a{display:inline-block;text-decoration:none;display:block}.store-switcher .actions.dropdown ul.dropdown-menu .dropdown-toolbar a:before{font-family:'icons-blank-theme';content:'\e606';font-size:20px;line-height:normal;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:text-top;text-align:center;margin:0 3px 0 -4px}.tooltip{display:inline-block;margin-left:5px}.tooltip .help span,.tooltip .help a{width:16px;height:16px;text-align:center;background:rgba(194,186,169,.5);cursor:pointer;border-radius:10px;vertical-align:middle;display:inline-block;text-decoration:none}.tooltip .help span:hover,.tooltip .help a:hover{background:#c2baa9}.tooltip .help span>span,.tooltip .help a>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tooltip .help span>span.focusable:active,.tooltip .help a>span.focusable:active,.tooltip .help span>span.focusable:focus,.tooltip .help a>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.tooltip .help span>span.focusable:active,.tooltip .help a>span.focusable:active,.tooltip .help span>span.focusable:focus,.tooltip .help a>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.tooltip .help span:before,.tooltip .help a:before{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;content:'?';font-size:13px;line-height:16px;color:#5a534a;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center}.tooltip .help span:before,.tooltip .help a:before{font-weight:700}.tooltip .tooltip-content{display:none;position:absolute;max-width:200px;margin-top:10px;margin-left:-19px;padding:4px 8px;border-radius:3px;background:#000;background:rgba(49,48,43,.8);color:#fff;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{content:'';position:absolute;width:0;height:0;top:-5px;left:20px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000;opacity:.8}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}button,.action-add.mselect-button-add{border-radius:2px;background-image:none;background:#f2ebde;padding:6px 13px;color:#645d53;border:1px solid #ada89e;cursor:pointer;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;line-height:1.4rem;box-sizing:border-box;margin:0;vertical-align:middle}button:focus,button:active,.action-add.mselect-button-add:focus,.action-add.mselect-button-add:active{background:#cac3b4;border:1px solid #989287}button:hover,.action-add.mselect-button-add:hover{background:#cac3b4}button.disabled,button[disabled],fieldset[disabled] button,.action-add.mselect-button-add.disabled,.action-add.mselect-button-add[disabled],fieldset[disabled] .action-add.mselect-button-add{cursor:default;pointer-events:none;opacity:.5}button.primary,.action-add.mselect-button-add.primary{background-image:none;background:#007dbd;padding:6px 13px;color:#fff;border:1px solid #0a6c9f;cursor:pointer;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;box-sizing:border-box;vertical-align:middle}button.primary:focus,button.primary:active,.action-add.mselect-button-add.primary:focus,.action-add.mselect-button-add.primary:active{background:#026294;border:1px solid #004c74;color:#fff}button.primary:hover,.action-add.mselect-button-add.primary:hover{background:#026294;border:1px solid #026294}button.primary.disabled,button.primary[disabled],fieldset[disabled] button.primary,.action-add.mselect-button-add.primary.disabled,.action-add.mselect-button-add.primary[disabled],fieldset[disabled] .action-add.mselect-button-add.primary{cursor:default;pointer-events:none;opacity:.5}.actions-split{display:inline-block;position:relative;vertical-align:middle}.actions-split button,.actions-split .action-add.mselect-button-add{margin-left:0!important}.actions-split:before,.actions-split:after{content:"";display:table}.actions-split:after{clear:both}.actions-split:before,.actions-split:after{content:"";display:table}.actions-split:after{clear:both}.actions-split .action-default{float:left;margin:0}.actions-split .action-toggle{float:right;margin:0}.actions-split button.action-default,.actions-split .action-add.mselect-button-add.action-default{border-top-right-radius:0;border-bottom-right-radius:0}.actions-split button+.action-toggle,.actions-split .action-add.mselect-button-add+.action-toggle{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.actions-split .action-toggle{padding:6px 5px;display:inline-block;text-decoration:none}.actions-split .action-toggle>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.actions-split .action-toggle>span.focusable:active,.actions-split .action-toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.actions-split .action-toggle>span.focusable:active,.actions-split .action-toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.actions-split .action-toggle:after{font-family:'icons-blank-theme';content:'\e607';font-size:22px;line-height:14px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.actions-split .action-toggle:hover:after{color:inherit}.actions-split .action-toggle:active:after{color:inherit}.actions-split .action-toggle.active{display:inline-block;text-decoration:none}.actions-split .action-toggle.active>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.actions-split .action-toggle.active>span.focusable:active,.actions-split .action-toggle.active>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.actions-split .action-toggle.active>span.focusable:active,.actions-split .action-toggle.active>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.actions-split .action-toggle.active:after{font-family:'icons-blank-theme';content:'\e618';font-size:22px;line-height:14px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.actions-split .action-toggle.active:hover:after{color:inherit}.actions-split .action-toggle.active:active:after{color:inherit}.actions-split .dropdown-menu{margin:0;padding:0;list-style:none none;box-sizing:border-box;background:#fff;border:1px solid #bbb;position:absolute;z-index:100;top:100%;min-width:175px;margin-top:4px;display:none;box-shadow:0 3px 3px rgba(0,0,0,.15)}.actions-split .dropdown-menu li{margin:0;padding:3px 5px}.actions-split .dropdown-menu li:hover{background:#e8e8e8;cursor:pointer}.actions-split .dropdown-menu:before,.actions-split .dropdown-menu:after{content:"";position:absolute;display:block;width:0;height:0;border-bottom-style:solid}.actions-split .dropdown-menu:before{z-index:99;border:solid 6px;border-color:transparent transparent #fff}.actions-split .dropdown-menu:after{z-index:98;border:solid 7px;border-color:transparent transparent #bbb}.actions-split .dropdown-menu:before{top:-12px;right:10px}.actions-split .dropdown-menu:after{top:-14px;right:9px}.actions-split.active{overflow:visible}.actions-split.active .dropdown-menu{display:block}.actions-split .action-toggle:after{height:13px}.page-content:after{content:"";display:table;clear:both}.page-wrapper>.page-content{margin-bottom:20px}.page-footer{padding:15px 0}.page-footer-wrapper{background-color:#e0dacf;margin-top:auto}.page-footer:after{content:"";display:table;clear:both}.footer-legal{float:right;width:550px}.footer-legal .link-report,.footer-legal .magento-version,.footer-legal .copyright{font-size:13px}.footer-legal:before{content:"";display:inline-block;vertical-align:middle;position:absolute;z-index:1;margin-top:2px;margin-left:-35px;width:30px;height:35px;background-size:109px 70px;background:url("../images/logo.svg") no-repeat 0 -21px}.icon-error{margin-left:15px;color:#c00815;font-size:11px}.icon-error:before{font-family:'MUI-Icons';content:"\e086";font-size:13px;line-height:13px;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center;margin:-1px 5px 0 0}.ui-widget-overlay{position:fixed}.control .nested{padding:0}.control *:first-child{margin-bottom:0}.field-tooltip{display:inline-block;vertical-align:top;margin-top:5px;position:relative;z-index:1;width:0;overflow:visible}.field-choice .field-tooltip{margin-top:10px}.field-tooltip:hover{z-index:99}.field-tooltip-action{position:relative;z-index:2;margin-left:18px;width:22px;height:22px;display:inline-block;cursor:pointer}.field-tooltip-action:before{content:"?";font-weight:500;font-size:18px;display:inline-block;overflow:hidden;height:22px;border-radius:11px;line-height:22px;width:22px;text-align:center;color:#fff;background-color:#514943}.field-tooltip-action span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.field-tooltip-action span.focusable:active,.field-tooltip-action span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.field-tooltip-action span.focusable:active,.field-tooltip-action span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.control-text:focus+.field-tooltip-content,.field-tooltip:hover .field-tooltip-content{display:block}.field-tooltip-content{display:none;position:absolute;z-index:1;width:320px;background:#fff8d7;padding:15px 25px;right:-66px;border:1px solid #adadad;border-radius:1px;bottom:42px;box-shadow:0 2px 8px 0 rgba(0,0,0,.3)}.field-tooltip-content:after,.field-tooltip-content:before{content:"";display:block;width:0;height:0;border:16px solid transparent;border-top-color:#adadad;position:absolute;right:20px;top:100%;z-index:3}.field-tooltip-content:after{border-top-color:#fff8d7;margin-top:-1px;z-index:4}.form__field.field-error .control [class*=control-]{border-color:#e22626}.form__field.field-error .control [class*=control-]:before{border-color:#e22626}.form__field .mage-error{border:1px solid #e22626;display:block;margin:2px 0 0;padding:6px 10px 10px;background:#fff8d6;color:#555;font-size:12px;font-weight:500;box-sizing:border-box;max-width:380px}.no-flexbox.no-flexboxlegacy .form__field .control-addon+.mage-error{display:inline-block;width:100%}.form__field{position:relative;z-index:1}.form__field:hover{z-index:2}.control .form__field{position:static}.form__field[data-config-scope]:before{content:attr(data-config-scope);display:inline-block;position:absolute;color:gray;right:0;top:6px}.control .form__field[data-config-scope]:nth-child(n+2):before{content:""}.form__field.field-disabled>.label{color:#999}.form__field.field-disabled.field .control [class*=control-][disabled]{background-color:#e9e9e9;opacity:.5;color:#303030;border-color:#adadad}.control-fields .label~.control{width:100%}.form__field{border:0;padding:0}.form__field .note{color:#303030;padding:0;margin:10px 0 0;max-width:380px}.form__field .note:before{display:none}.form__field.form__field{margin-bottom:0}.form__field.form__field+.form__field.form__field{margin-top:15px}.form__field.form__field:not(.choice)~.choice{margin-left:20px;margin-top:5px}.form__field.form__field.choice~.choice{margin-top:9px}.form__field.form__field~.choice:last-child{margin-bottom:8px}.fieldset>.form__field{margin-bottom:30px}.form__field .label{color:#303030}.form__field:not(.choice)>.label{font-size:14px;font-weight:600;width:30%;padding-right:30px;padding-top:0;line-height:33px;white-space:nowrap}.form__field:not(.choice)>.label:before{content:".";visibility:hidden;width:0;margin-left:-7px;overflow:hidden}.form__field:not(.choice)>.label span{white-space:normal;display:inline-block;vertical-align:middle;line-height:1.2}.form__field.required>.label:after{content:"";margin-left:0}.form__field.required>.label span:after{content:"*";color:#eb5202;display:inline;font-weight:500;font-size:16px;margin-top:2px;position:absolute;z-index:1;margin-left:10px}.form__field .control-file{margin-top:6px}.form__field .control-select{line-height:33px}.form__field .control-select:not([multiple]),.form__field .control-text{height:33px;max-width:380px}.form__field .control-addon{max-width:380px}.form__field .control-textarea,.form__field .control-select,.form__field .control-text{border:1px solid #adadad;border-radius:1px;padding:0 10px;color:#303030;background-color:#fff;font-weight:500;font-size:15px;min-width:11em}.form__field .control-textarea:focus,.form__field .control-select:focus,.form__field .control-text:focus{outline:0;border-color:#007bdb;box-shadow:none}.form__field .control-text{line-height:auto}.form__field .control-textarea{padding-top:6px;padding-bottom:6px;line-height:1.18em}.form__field .control-select[multiple],.form__field .control-textarea{width:100%;height:calc(6*1.2em + 14px)}.form__field .control-value{display:inline-block;padding:6px 10px}.form__field .control-fields .form__field:nth-child(n+2):not(.choice)>.label{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.form__field .control-fields .form__field:nth-child(n+2):not(.choice)>.label.focusable:active,.form__field .control-fields .form__field:nth-child(n+2):not(.choice)>.label.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.form__field .control-fields .form__field:nth-child(n+2):not(.choice)>.label.focusable:active,.form__field .control-fields .form__field:nth-child(n+2):not(.choice)>.label.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.form__field .control-select{padding:0}.form__field .control-select option{box-sizing:border-box;padding:4px 10px;display:block}.form__field .control-select optgroup{font-weight:600;display:block;padding:4px 10px;line-height:33px;list-style:inside;font-style:normal}.form__field .control-range>.form__field:nth-child(2):before{content:"\2014";content:":";display:inline-block;margin-left:-25px;float:left;width:20px;line-height:33px;text-align:center}.form__field.choice{position:relative;z-index:1;padding-top:8px;padding-left:26px;padding-right:0}.form__field.choice .label{font-weight:500;padding:0;display:inline;float:none;line-height:18px}.form__field.choice input{position:absolute;top:8px;margin-top:3px!important}.form__field.choice input[disabled]+.label{opacity:.5;cursor:not-allowed}.control>.form__field.choice{max-width:380px}.control>.form__field.choice:nth-child(1):nth-last-child(2),.control>.form__field.choice:nth-child(2):nth-last-child(1){display:inline-block}.control>.form__field.choice:nth-child(1):nth-last-child(2)+.choice,.control>.form__field.choice:nth-child(2):nth-last-child(1)+.choice{margin-left:41px;margin-top:0}.control>.form__field.choice:nth-child(1):nth-last-child(2)+.choice:before,.control>.form__field.choice:nth-child(2):nth-last-child(1)+.choice:before{content:"";position:absolute;display:inline-block;height:20px;top:8px;left:-20px;width:1px;background:#ccc}.form__field.choice .label{cursor:pointer}.form__field.choice .label:before{content:"";position:absolute;z-index:1;border:1px solid #adadad;width:14px;height:14px;top:10px;left:0;border-radius:2px;background:url("../Magento_Ui/images/choice_bkg.png") no-repeat -100% -100%}.form__field.choice input:focus+.label:before{outline:0;border-color:#007bdb}.form__field.choice .control-radio+.label:before{border-radius:8px}.form__field.choice .control-radio:checked+.label:before{background-position:-26px -1px}.form__field.choice .control-checkbox:checked+.label:before{background-position:-1px -1px}.form__field.choice input{opacity:0}.fieldset>.form__field.choice{margin-left:30%}.form__field .control-after,.form__field .control-before{border:0;color:#858585;font-weight:300;font-size:15px;line-height:33px;display:inline-block;height:33px;box-sizing:border-box;padding:0 3px}.no-flexbox.no-flexboxlegacy .form__field .control-before,.no-flexbox.no-flexboxlegacy .form__field .control-addon{float:left;white-space:nowrap}.form__field .control-addon{display:inline-flex;max-width:380px;width:100%;flex-flow:row nowrap;position:relative;z-index:1}.form__field .control-addon>*{position:relative;z-index:1}.form__field .control-addon .control-text[disabled][type],.form__field .control-addon .control-select[disabled][type],.form__field .control-addon .control-select,.form__field .control-addon .control-text{background:transparent!important;border:0;width:auto;vertical-align:top;order:1;flex:1}.form__field .control-addon .control-text[disabled][type]:focus,.form__field .control-addon .control-select[disabled][type]:focus,.form__field .control-addon .control-select:focus,.form__field .control-addon .control-text:focus{box-shadow:none}.form__field .control-addon .control-text[disabled][type]:focus+label:before,.form__field .control-addon .control-select[disabled][type]:focus+label:before,.form__field .control-addon .control-select:focus+label:before,.form__field .control-addon .control-text:focus+label:before{outline:0;border-color:#007bdb}.form__field .control-addon .control-text[disabled][type]+label,.form__field .control-addon .control-select[disabled][type]+label,.form__field .control-addon .control-select+label,.form__field .control-addon .control-text+label{padding-left:10px;position:static!important;z-index:0}.form__field .control-addon .control-text[disabled][type]+label>*,.form__field .control-addon .control-select[disabled][type]+label>*,.form__field .control-addon .control-select+label>*,.form__field .control-addon .control-text+label>*{vertical-align:top;position:relative;z-index:2}.form__field .control-addon .control-text[disabled][type]+label:before,.form__field .control-addon .control-select[disabled][type]+label:before,.form__field .control-addon .control-select+label:before,.form__field .control-addon .control-text+label:before{box-sizing:border-box;border-radius:1px;border:1px solid #adadad;content:"";display:block;position:absolute;top:0;left:0;width:100%;height:100%;z-index:0;background:#fff}.form__field .control-addon .control-text[disabled][type][disabled]+label:before,.form__field .control-addon .control-select[disabled][type][disabled]+label:before,.form__field .control-addon .control-select[disabled]+label:before,.form__field .control-addon .control-text[disabled]+label:before{opacity:.5;background:#e9e9e9}.form__field .control-after{order:3}.form__field .control-after:last-child{padding-right:10px}.form__field .control-before{order:0}.form__field .control-some{display:flex}.form__field [class*=control-grouped]{display:table;width:100%;table-layout:fixed;box-sizing:border-box}.form__field [class*=control-grouped]>.form__field{display:table-cell;width:50%;vertical-align:top}.form__field [class*=control-grouped]>.form__field>.control{width:100%;float:none}.form__field [class*=control-grouped]>.form__field:nth-child(n+2){padding-left:20px}.form__field [class*=control-grouped]>.form__field:nth-child(n+2):not(.choice) .label{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.form__field [class*=control-grouped]>.form__field:nth-child(n+2):not(.choice) .label.focusable:active,.form__field [class*=control-grouped]>.form__field:nth-child(n+2):not(.choice) .label.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.form__field [class*=control-grouped]>.form__field:nth-child(n+2):not(.choice) .label.focusable:active,.form__field [class*=control-grouped]>.form__field:nth-child(n+2):not(.choice) .label.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.form__field [required]{box-shadow:none}fieldset.form__field{position:relative}fieldset.form__field [class*=control-grouped]>.form__field:first-child>.label,fieldset.form__field .control-fields>.form__field:first-child>.label{position:absolute;left:0;top:0;opacity:0;cursor:pointer;width:30%}.control-text+.ui-datepicker-trigger{background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;line-height:inherit;font-weight:400;text-decoration:none;margin-left:-40px;display:inline-block}.control-text+.ui-datepicker-trigger img{display:none}.control-text+.ui-datepicker-trigger:focus,.control-text+.ui-datepicker-trigger:active{background:0 0;border:none}.control-text+.ui-datepicker-trigger:hover{background:0 0;border:none}.control-text+.ui-datepicker-trigger.disabled,.control-text+.ui-datepicker-trigger[disabled],fieldset[disabled] .control-text+.ui-datepicker-trigger{cursor:not-allowed;pointer-events:none;opacity:.5}.control-text+.ui-datepicker-trigger>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.control-text+.ui-datepicker-trigger>span.focusable:active,.control-text+.ui-datepicker-trigger>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.control-text+.ui-datepicker-trigger>span.focusable:active,.control-text+.ui-datepicker-trigger>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.control-text+.ui-datepicker-trigger:after{font-family:'icons-blank-theme';content:'\e612';font-size:38px;line-height:33px;color:#514943;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}[class*=tab-nav-item]:not(ul):active,[class*=tab-nav-item]:not(ul):focus{box-shadow:none;outline:none}.customer-index-edit .col-2-left-layout,.customer-index-edit .col-1-layout{background:#fff}.customer-index-edit{background:#fff}.customer-index-edit .col-2-left-layout{background:#fff}.customer-index-edit .main-col{padding-left:40px}.customer-index-edit .page-main-actions{background:0 0}.tab-nav.block{margin-bottom:40px}.tab-nav.block:first-child{margin-top:16px}.tab-nav.block .block-title{padding:7px 20px}.tab-nav-items{padding:0;border:1px solid #d3d3d3;box-shadow:0 0 4px rgba(50,50,50,.35);margin:0 0 40px;background:#f7f7f7}.tab-nav-item{padding:0;list-style-type:none;border-bottom:1px solid #e0e0e0;position:relative;margin:0 15px;z-index:1}.tab-nav-item:last-child{border-bottom:0}.tab-nav-item.ui-state-active{z-index:2;background:#fff;padding:1px 14px;border:2px solid #eb5202;margin:-1px}.tab-nav-item.ui-state-active .tab-nav-item-link{padding:13px 15px 13px;color:#eb5202}.tab-nav-item.ui-tabs-loading{position:relative;z-index:1}.tab-nav-item.ui-tabs-loading:before{content:"";display:block;position:absolute;z-index:2;background:url("../images/loader-2.gif") no-repeat 50% 50%;background-size:120px;width:20px;height:20px;top:13px;left:-10px}.tab-nav-item.ui-tabs-loading.ui-state-active:before{top:12px;left:4px}.tab-nav-item-link{display:block;padding:15px;color:#666;line-height:1}.tab-nav-item-link:focus,.tab-nav-item-link:active,.tab-nav-item-link:hover{outline:0;color:#eb5202;text-decoration:none}.ui-state-active .tab-nav-item-link{color:#666;font-weight:600}.tab-nav-item-link.changed{font-style:italic}.listing-tiles{overflow:hidden;margin-top:-10px;margin-left:-10px}.listing-tiles .listing-tile{background-color:#f2ebde;display:block;width:238px;height:200px;float:left;border:1px solid #676056;margin-top:10px;margin-left:10px;border-radius:4px;text-align:center}.listing-tiles .listing-tile.disabled{border-color:red}.listing-tiles .listing-tile.enabled{border-color:green}.listing .disabled{color:red}.listing .enabled{color:green}.pager{text-align:left;padding-bottom:10px}.pager:before,.pager:after{content:"";display:table}.pager:after{clear:both}.pager:before,.pager:after{content:"";display:table}.pager:after{clear:both}.pager [data-part=left]{display:inline-block;width:45%;float:left;text-align:left}.pager [data-part=right]{display:inline-block;width:45%;text-align:right;float:right;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.pager .action-next{cursor:pointer}.pager .action-previous{cursor:pointer}.pager{text-align:left}.pager [data-part=left]{display:inline-block;width:45%;text-align:left}.pager [data-part=right]{display:inline-block;width:45%;text-align:right;float:right}.grid .col-title{min-width:90px;text-align:center}.grid-actions [data-part=search]{display:inline-block;margin:0 30px}.grid-actions [data-part=search] input[type=text]{vertical-align:bottom;width:460px}.grid .actions-split .dropdown-menu{right:auto;left:auto;text-align:left;color:#676056;font-weight:400}.grid .actions-split .dropdown-menu:after{right:auto;left:9px}.grid .actions-split .dropdown-menu:before{right:auto;left:10px}.grid .grid-actions{padding:10px 0}.grid .hor-scroll{padding-top:10px}.grid .select-box{display:inline-block;vertical-align:top;margin:-12px -10px -7px;padding:12px 10px 7px;width:100%}.filters-toggle{background:#f2ebde;padding:6px 13px;color:#645d53;border:1px solid #ada89e;cursor:pointer;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;line-height:1.4rem;box-sizing:border-box;margin:3px;vertical-align:middle;display:inline-block;background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400}.filters-toggle:after{font-family:'icons-blank-theme';content:'\e607';font-size:30px;line-height:15px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.filters-toggle:hover:after{color:inherit}.filters-toggle:active:after{color:inherit}.filters-toggle:focus,.filters-toggle:active{background:#cac3b4;border:1px solid #989287}.filters-toggle:hover{background:#cac3b4}.filters-toggle.disabled,.filters-toggle[disabled],fieldset[disabled] .filters-toggle{cursor:default;pointer-events:none;opacity:.5}.filters-toggle:focus,.filters-toggle:active{background:0 0;border:none}.filters-toggle:hover{background:0 0;border:none}.filters-toggle.disabled,.filters-toggle[disabled],fieldset[disabled] .filters-toggle{cursor:not-allowed;pointer-events:none;opacity:.5}.filters-toggle:after{margin-top:2px;margin-left:-3px}.filters-toggle.active:after{content:'\e618'}.filters-current{padding:10px 0;display:none}.filters-current.active{display:block}.filters-items{margin:0;padding:0;list-style:none none;display:inline}.filters-item{display:inline-block;margin:0 5px 5px 0;padding:2px 2px 2px 4px;border-radius:3px;background:#f7f3eb}.filters-item .item-label{font-weight:600}.filters-item .item-label:after{content:": "}.filters-item .action-remove{background-image:none;background:#f2ebde;padding:6px 13px;color:#645d53;border:1px solid #ada89e;cursor:pointer;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;line-height:1.4rem;box-sizing:border-box;margin:3px;vertical-align:middle;display:inline-block;text-decoration:none;padding:0}.filters-item .action-remove>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.filters-item .action-remove>span.focusable:active,.filters-item .action-remove>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters-item .action-remove>span.focusable:active,.filters-item .action-remove>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters-item .action-remove:before{font-family:'icons-blank-theme';content:'\e616';font-size:16px;line-height:16px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.filters-item .action-remove:hover:before{color:inherit}.filters-item .action-remove:active:before{color:inherit}.filters-item .action-remove:focus,.filters-item .action-remove:active{background:#cac3b4;border:1px solid #989287}.filters-item .action-remove:hover{background:#cac3b4}.filters-item .action-remove.disabled,.filters-item .action-remove[disabled],fieldset[disabled] .filters-item .action-remove{cursor:default;pointer-events:none;opacity:.5}.filters-form{position:relative;z-index:1;margin:14px 0;background:#fff;border:1px solid #bbb;box-shadow:0 3px 3px rgba(0,0,0,.15)}.filters-form .action-close{position:absolute;top:3px;right:7px;background:#f2ebde;padding:6px 13px;color:#645d53;border:1px solid #ada89e;cursor:pointer;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;line-height:1.4rem;box-sizing:border-box;margin:3px;vertical-align:middle;display:inline-block;background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400}.filters-form .action-close>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.filters-form .action-close>span.focusable:active,.filters-form .action-close>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters-form .action-close>span.focusable:active,.filters-form .action-close>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters-form .action-close:before{font-family:'icons-blank-theme';content:'\e616';font-size:42px;line-height:42px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.filters-form .action-close:hover:before{color:inherit}.filters-form .action-close:active:before{color:inherit}.filters-form .action-close:focus,.filters-form .action-close:active{background:#cac3b4;border:1px solid #989287}.filters-form .action-close:hover{background:#cac3b4}.filters-form .action-close.disabled,.filters-form .action-close[disabled],fieldset[disabled] .filters-form .action-close{cursor:default;pointer-events:none;opacity:.5}.filters-form .action-close:focus,.filters-form .action-close:active{background:0 0;border:none}.filters-form .action-close:hover{background:0 0;border:none}.filters-form .action-close.disabled,.filters-form .action-close[disabled],fieldset[disabled] .filters-form .action-close{cursor:not-allowed;pointer-events:none;opacity:.5}.filters-actions{margin:18px;text-align:right}.filters-fieldset{padding-bottom:0}.filters-fieldset .field{border:0;margin:0 0 20px;box-sizing:border-box;display:inline-block;padding:0 12px 0 0;width:33.33333333%;vertical-align:top}.filters-fieldset .field:before,.filters-fieldset .field:after{content:"";display:table}.filters-fieldset .field:after{clear:both}.filters-fieldset .field:before,.filters-fieldset .field:after{content:"";display:table}.filters-fieldset .field:after{clear:both}.filters-fieldset .field.choice:before,.filters-fieldset .field.no-label:before{box-sizing:border-box;content:" ";height:1px;float:left;padding:6px 15px 0 0;width:35%}.filters-fieldset .field .description{box-sizing:border-box;float:left;padding:6px 15px 0 0;text-align:right;width:35%}.filters-fieldset .field:not(.choice)>.label{box-sizing:border-box;float:left;padding:6px 15px 0 0;text-align:right;width:35%}.filters-fieldset .field:not(.choice)>.control{float:left;width:65%}.filters-fieldset .field:last-child{margin-bottom:0}.filters-fieldset .field+.fieldset{clear:both}.filters-fieldset .field>.label{font-weight:700}.filters-fieldset .field>.label+br{display:none}.filters-fieldset .field .choice input{vertical-align:top}.filters-fieldset .field .fields.group:before,.filters-fieldset .field .fields.group:after{content:"";display:table}.filters-fieldset .field .fields.group:after{clear:both}.filters-fieldset .field .fields.group:before,.filters-fieldset .field .fields.group:after{content:"";display:table}.filters-fieldset .field .fields.group:after{clear:both}.filters-fieldset .field .fields.group .field{box-sizing:border-box;float:left}.filters-fieldset .field .fields.group.group-2 .field{width:50% !important}.filters-fieldset .field .fields.group.group-3 .field{width:33.3% !important}.filters-fieldset .field .fields.group.group-4 .field{width:25% !important}.filters-fieldset .field .fields.group.group-5 .field{width:20% !important}.filters-fieldset .field .addon{display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;padding:0;width:100%}.filters-fieldset .field .addon textarea,.filters-fieldset .field .addon select,.filters-fieldset .field .addon input{-ms-flex-order:2;-webkit-order:2;order:2;-webkit-flex-basis:100%;flex-basis:100%;box-shadow:none;display:inline-block;margin:0;width:auto}.filters-fieldset .field .addon .addbefore,.filters-fieldset .field .addon .addafter{-ms-flex-order:3;-webkit-order:3;order:3;display:inline-block;box-sizing:border-box;background:#fff;border:1px solid #c2c2c2;border-radius:1px;height:32px;width:100%;padding:0 9px;font-size:14px;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;line-height:1.428571429;background-clip:padding-box;vertical-align:baseline;width:auto;white-space:nowrap;vertical-align:middle}.filters-fieldset .field .addon .addbefore:disabled,.filters-fieldset .field .addon .addafter:disabled{opacity:.5}.filters-fieldset .field .addon .addbefore::-moz-placeholder,.filters-fieldset .field .addon .addafter::-moz-placeholder{color:#c2c2c2}.filters-fieldset .field .addon .addbefore::-webkit-input-placeholder,.filters-fieldset .field .addon .addafter::-webkit-input-placeholder{color:#c2c2c2}.filters-fieldset .field .addon .addbefore:-ms-input-placeholder,.filters-fieldset .field .addon .addafter:-ms-input-placeholder{color:#c2c2c2}.filters-fieldset .field .addon .addbefore{float:left;-ms-flex-order:1;-webkit-order:1;order:1}.filters-fieldset .field .additional{margin-top:10px}.filters-fieldset .field.required>.label:after{content:'*';font-size:1.2rem;color:#e02b27;margin:0 0 0 5px}.filters-fieldset .field .note{font-size:1.2rem;margin:3px 0 0;padding:0;display:inline-block;text-decoration:none}.filters-fieldset .field .note:before{font-family:'icons-blank-theme';content:'\e618';font-size:24px;line-height:12px;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.filters-fieldset .field .label{color:#676056;font-size:13px;font-weight:600;margin:0}.filters .field-date .group .hasDatepicker{width:100%;padding-right:30px}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger{background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;line-height:inherit;font-weight:400;text-decoration:none;margin-left:-33px;display:inline-block;width:30px}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger img{display:none}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger:focus,.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger:active{background:0 0;border:none}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger:hover{background:0 0;border:none}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger.disabled,.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger[disabled],fieldset[disabled] .filters .field-date .group .hasDatepicker+.ui-datepicker-trigger{cursor:not-allowed;pointer-events:none;opacity:.5}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger>span.focusable:active,.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger>span.focusable:active,.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger:after{font-family:'icons-blank-theme';content:'\e612';font-size:35px;line-height:30px;color:#514943;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.filters .field-range .group .field{margin-bottom:0}.filters .field-range .group .control{width:100%;box-sizing:border-box;padding-right:0;position:relative;z-index:1}.mass-select{position:relative;margin:-6px -10px;padding:6px 2px 6px 10px;z-index:1;white-space:nowrap}.mass-select.active{background:rgba(0,0,0,.2)}.mass-select-toggle{background:#f2ebde;padding:6px 13px;color:#645d53;border:1px solid #ada89e;cursor:pointer;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;line-height:1.4rem;box-sizing:border-box;margin:3px;vertical-align:middle;display:inline-block;background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400}.mass-select-toggle>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.mass-select-toggle>span.focusable:active,.mass-select-toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.mass-select-toggle>span.focusable:active,.mass-select-toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.mass-select-toggle:before{font-family:'icons-blank-theme';content:'\e607';font-size:30px;line-height:15px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.mass-select-toggle:hover:before{color:inherit}.mass-select-toggle:active:before{color:inherit}.mass-select-toggle:focus,.mass-select-toggle:active{background:#cac3b4;border:1px solid #989287}.mass-select-toggle:hover{background:#cac3b4}.mass-select-toggle.disabled,.mass-select-toggle[disabled],fieldset[disabled] .mass-select-toggle{cursor:default;pointer-events:none;opacity:.5}.mass-select-toggle:focus,.mass-select-toggle:active{background:0 0;border:none}.mass-select-toggle:hover{background:0 0;border:none}.mass-select-toggle.disabled,.mass-select-toggle[disabled],fieldset[disabled] .mass-select-toggle{cursor:not-allowed;pointer-events:none;opacity:.5}.mass-select-toggle:before{margin-top:-2px;text-indent:-5px;color:#fff}.mass-select-toggle:hover:before{color:#fff}.mass-select-toggle:active:before,.mass-select-toggle.active:before{content:'\e618'}.mass-select-field{display:inline}.mass-select-menu{display:none;position:absolute;top:100%;left:0;text-align:left;margin:0;padding:0;list-style:none none;background:#fff;border:1px solid #bbb;min-width:175px;box-shadow:0 3px 3px rgba(0,0,0,.15)}.mass-select-menu li{margin:0;padding:4px 15px;border-bottom:1px solid #e5e5e5}.mass-select-menu li:hover{background:#e8e8e8;cursor:pointer}.mass-select-menu span{font-weight:400;font-size:13px;color:#645d53}.mass-select-menu.active{display:block}.grid-loading-mask{position:absolute;left:0;top:0;right:0;bottom:0;background:rgba(255,255,255,.5);z-index:100}.grid-loading-mask .grid-loader{position:absolute;margin:auto;left:0;top:0;right:0;bottom:0;width:218px;height:149px;background:url('../images/loader-2.gif') 50% 50% no-repeat}.addon input{border-width:1px 0 1px 1px}.addon input~.addafter strong{display:inline-block;background:#fff;line-height:24px;margin:0 3px 0 -2px;padding-left:4px;padding-right:4px;position:relative;font-size:12px;top:0}.addon input:focus~.addafter{border-color:#75b9f0;box-shadow:0 0 8px rgba(82,168,236,.6)}.addon input:focus~.addafter strong{margin-top:0}.addon .addafter{background:0 0;color:#a6a6a6;border-width:1px 1px 1px 0;border-radius:2px 2px 0 0;padding:0;border-color:#ada89e}.addon .pager input{border-width:1px}.field .control input[type=text][disabled],.field .control input[type=text][disabled]~.addafter,.field .control select[disabled],.field .control select[disabled]~.addafter{background-color:#fff;border-color:#eee;box-shadow:none;color:#999}.field .control input[type=text][disabled]~.addafter strong,.field .control select[disabled]~.addafter strong{background-color:#fff}.field-price.addon{direction:rtl}.field-price.addon>*{direction:ltr}.field-price.addon .addafter{border-width:1px 0 1px 1px;border-radius:2px 0 0 2px}.field-price.addon input:first-child{border-radius:0 2px 2px 0}.field-price input{border-width:1px 1px 1px 0}.field-price input:focus{box-shadow:0 0 8px rgba(82,168,236,.6)}.field-price input:focus~label.addafter{box-shadow:0 0 8px rgba(82,168,236,.6)}.field-price input~label.addafter strong{margin-left:2px;margin-right:-2px}.field-price.addon>input{width:99px;float:left}.field-price .control{position:relative}.field-price label.mage-error{position:absolute;left:0;top:30px}.version-fieldset .grid-actions{border-bottom:1px solid #f2ebde;margin:0 0 15px;padding:0 0 15px}.navigation>ul,.message-system,.page-header,.page-actions.fixed .page-actions-inner,.page-content,.page-footer{width:auto;min-width:960px;max-width:1300px;margin:0 auto;padding-left:15px;padding-right:15px;box-sizing:border-box;width:100%}.pager label.page,.filters .field-range .group .label,.mass-select-field .label{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visually-hidden.focusable:active,.visually-hidden.focusable:focus,.pager label.page.focusable:active,.pager label.page.focusable:focus,.filters .field-range .group .label.focusable:active,.filters .field-range .group .label.focusable:focus,.mass-select-field .label.focusable:active,.mass-select-field .label.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}table th.required:after,.data-table th.required-entry:after,.data-table td.required-entry:after,.grid-actions .filter.required .label span:after,.grid-actions .required:after,.accordion .config .data-table td.required-entry:after{content:'*';color:#e22626;font-weight:400;margin-left:3px}.grid th.required:after,.grid th .required:after{content:'*';color:#f9d4d4;font-weight:400;margin-left:3px}.grid td.col-period,.grid td.col-date,.grid td.col-date_to,.grid td.col-date_from,.grid td.col-ended_at,.grid td.col-created_at,.grid td.col-updated_at,.grid td.col-customer_since,.grid td.col-session_start_time,.grid td.col-last_activity,.grid td.col-email,.grid td.col-name,.grid td.col-sku,.grid td.col-firstname,.grid td.col-lastname,.grid td.col-title,.grid td.col-label,.grid td.col-product,.grid td.col-set_name,.grid td.col-websites,.grid td.col-time,.grid td.col-billing_name,.grid td.col-shipping_name,.grid td.col-phone,.grid td.col-type,.product-options .grouped-items-table .col-name,.product-options .grouped-items-table .col-sku,.sales-order-create-index .data-table .col-product,[class^=' adminhtml-rma-'] .fieldset-wrapper .data-table td,[class^=' adminhtml-rma-'] .grid .col-product_sku,[class^=' adminhtml-rma-'] .grid .col-product_name,.col-grid_segment_name,.adminhtml-catalog-event-index .col-category,[class^=' catalog-search'] .col-search_query,[class^=' catalog-search'] .col-synonym_for,[class^=' catalog-search'] .col-redirect,.adminhtml-urlrewrite-index .col-request_path,.adminhtml-cms-page-index .col-title,.adminhtml-cms-page-index .col-identifier,.adminhtml-cms-hierarchy-index .col-title,.adminhtml-cms-hierarchy-index .col-identifier,.col-banner_name,.adminhtml-widget-instance-index .col-title,.reports-index-search .col-query_text,.adminhtml-rma-item-attribute-index .grid .col-attr-code,.adminhtml-system-store-index .grid td,.catalog-product-attribute-index .col-attr-code,.catalog-product-attribute-index .col-label,.adminhtml-export-index .col-code,.adminhtml-logging-index .grid .col-fullaction,.adminhtml-system-variable-index .grid .col-code,.adminhtml-logging-index .grid .col-info,.dashboard-secondary .dashboard-item tr>td:first-child,.ui-tabs-panel .dashboard-data .col-name,.data-table-td-max .data-table td,[class^=' adminhtml-rma-'] .fieldset-wrapper .accordion .config .data-table td,.data-table-td-max .accordion .config .data-table td,.order-account-information .data-table td,[class^=' adminhtml-rma-'] .rma-request-details .data-table td{overflow:hidden;text-overflow:ellipsis}td.col-period,td.col-date,td.col-date_to,td.col-date_from,td.col-ended_at,td.col-created_at,td.col-updated_at,td.col-customer_since,td.col-session_start_time,td.col-time,td.col-sku,td.col-type,[class^=' adminhtml-rma-'] #rma_items_grid_table .headings th,.adminhtml-process-list .col-action a,.adminhtml-process-list .col-mode{white-space:nowrap}table thead tr th:first-child,table tfoot tr th:first-child,table tfoot tr td:first-child{border-left:0}table thead tr th:last-child,table tfoot tr th:last-child,table tfoot tr td:last-child{border-right:0}.form-inline .grid-actions .label,.form-inline .massaction .label{padding:0;width:auto}.grid .col-action,.grid .col-actions,.grid .col-qty,.grid .col-purchases,.catalog-product-edit .ui-tabs-panel .grid .col-price,.catalog-product-edit .ui-tabs-panel .grid .col-position{width:50px}.grid .col-order-number,.grid .col-real_order_id,.grid .col-invoice-number,.grid .col-increment_id,.grid .col-transaction-id,.grid .col-parent-transaction-id,.grid .col-reference_id,.grid .col-status,.grid .col-price,.grid .col-position,.grid .col-base_grand_total,.grid .col-grand_total,.grid .col-sort_order,.grid .col-carts,.grid .col-priority,.grid .col-severity,.sales-order-create-index .col-in_products,[class^=' reports-'] [class^=col-total],[class^=' reports-'] [class^=col-average],[class^=' reports-'] [class^=col-ref-],[class^=' reports-'] [class^=col-rate],[class^=' reports-'] [class^=col-tax-amount],[class^=' adminhtml-customer-'] .col-required,.adminhtml-rma-item-attribute-index .col-required,[class^=' adminhtml-customer-'] .col-system,.adminhtml-rma-item-attribute-index .col-system,[class^=' adminhtml-customer-'] .col-is_visible,.adminhtml-rma-item-attribute-index .col-is_visible,[class^=' adminhtml-customer-'] .col-sort_order,.adminhtml-rma-item-attribute-index .col-sort_order,.catalog-product-attribute-index [class^=' col-is_'],.catalog-product-attribute-index .col-required,.catalog-product-attribute-index .col-system,.adminhtml-test-index .col-is_listed,[class^=' tests-report-test'] [class^=col-inv-]{width:70px}.grid .col-phone,.sales-order-view .grid .col-period,.sales-order-create-index .col-phone,[class^=' adminhtml-rma-'] .grid .col-product_sku,.adminhtml-rma-edit .col-product,.adminhtml-rma-edit .col-sku,.catalog-product-edit .ui-tabs-panel .grid .col-name,.catalog-product-edit .ui-tabs-panel .grid .col-type,.catalog-product-edit .ui-tabs-panel .grid .col-sku,.customer-index-index .grid .col-customer_since,.customer-index-index .grid .col-billing_country_id,[class^=' customer-index-'] .fieldset-wrapper .grid .col-created_at,[class^=' customer-index-'] .accordion .grid .col-created_at{max-width:70px;width:70px}.sales-order-view .grid .col-name,.sales-order-create-index .data-table .col-product,[class^=' adminhtml-rma-'] .grid .col-name,[class^=' adminhtml-rma-'] .grid .col-product,[class^=' catalog-search'] .col-search_query,[class^=' catalog-search'] .col-synonym_for,[class^=' catalog-search'] .col-redirect,.adminhtml-urlrewrite-index .col-request_path,.reports-report-shopcart-abandoned .grid .col-name,.tax-rule-index .grid .col-title,.adminhtml-rma-item-attribute-index .grid .col-attr-code,.dashboard-secondary .dashboard-item tr>td:first-child{max-width:150px;width:150px}[class^=' sales-order-'] .grid .col-name,.catalog-category-edit .grid .col-name,.adminhtml-catalog-event-index .col-category,.adminhtml-banner-edit .grid .col-name,.reports-report-product-lowstock .grid .col-sku,.newsletter-problem-index .grid .col-name,.newsletter-problem-index .grid .col-subject,.newsletter-problem-index .grid .col-product,.adminhtml-rma-item-attribute-index .grid .col-label,.adminhtml-export-index .col-label,.adminhtml-export-index .col-code,.adminhtml-scheduled-operation-index .grid .col-name,.adminhtml-logging-index .grid .col-fullaction,.test-report-customer-wishlist-wishlist .grid .col-name,.test-report-customer-wishlist-wishlist .grid .col-subject,.test-report-customer-wishlist-wishlist .grid .col-product{max-width:220px;width:220px}.grid .col-period,.grid .col-date,.grid .col-date_to,.grid .col-date_from,.grid .col-ended_at,.grid .col-created_at,.grid .col-updated_at,.grid .col-customer_since,.grid .col-session_start_time,.grid .col-last_activity,.grid .col-email,.grid .col-items_total,.grid .col-firstname,.grid .col-lastname,.grid .col-status-default,.grid .col-websites,.grid .col-time,.grid .col-billing_name,.grid .col-shipping_name,.sales-order-index .grid .col-name,.product-options .grouped-items-table .col-name,.product-options .grouped-items-table .col-sku,[class^=' sales-order-view'] .grid .col-customer_name,[class^=' adminhtml-rma-'] .grid .col-product_name,.catalog-product-index .grid .col-name,.catalog-product-review-index .grid .col-name,.catalog-product-review-index .grid .col-title,.customer-index-edit .ui-tabs-panel .grid .col-name,.review-product-index .grid .col-name,.adminhtml-cms-page-index .col-title,.adminhtml-cms-page-index .col-identifier,.catalog-product-attribute-index .col-attr-code,.catalog-product-attribute-index .col-label,.adminhtml-logging-index .grid .col-info{max-width:110px;width:110px}.grid .col-name,.grid .col-product,.col-banner_name,.adminhtml-widget-instance-index .col-title,[class^=' adminhtml-customer-'] .col-label,.adminhtml-rma-item-attribute-index .col-label,.adminhtml-system-variable-index .grid .col-code,.ui-tabs-panel .dashboard-data .col-name,.adminhtml-test-index .col-label{max-width:370px;width:370px}.col-grid_segment_name,.reports-index-search .col-query_text{max-width:570px;width:570px}[class^=' adminhtml-rma-'] .fieldset-wrapper .data-table td,.reports-report-product-lowstock .grid .col-name,.reports-report-shopcart-product .grid .col-name,.reports-report-review-customer .grid .col-name,[class^=' adminhtml-rma-'] .fieldset-wrapper .accordion .config .data-table td{max-width:670px;width:670px}.reports-report-sales-invoiced .grid .col-period,.reports-report-sales-refunde .grid .col-period,[class^=' tests-report-test'] .grid .col-period{width:auto}.grid .col-select,.grid .col-id,.grid .col-number{width:40px}.sales-order-create-index .grid,.sales-order-create-index .grid-actions,.adminhtml-export-index .grid-actions,.adminhtml-export-index .grid{padding-left:0;padding-right:0}[class^=' adminhtml-rma-'] .col-actions a,[class^=' customer-index-'] .col-action a,.adminhtml-notification-index .col-actions a{display:block;margin:0 0 3px;white-space:nowrap}.data-table-td-max .accordion .config .data-table td,.order-account-information .data-table td,[class^=' adminhtml-rma-'] .rma-request-details .data-table td{max-width:250px;width:250px}.catalog-product-edit .ui-tabs-panel .grid .hor-scroll,.catalog-product-index .grid .hor-scroll,.review-product-index .grid .hor-scroll,.adminhtml-rma-edit .hor-scroll{overflow-x:auto}.add-clearer:after,.massaction:after,.navigation>ul:after{content:"";display:table;clear:both}.test-content{width:calc(20px + 100*0.2)}.test-content:before{content:'.test {\A ' attr(data-attribute) ': 0.2em;' '\A content:\'';white-space:pre}.test-content:after{content:' Test\';\A}' "\A" '\A.test + .test._other ~ ul > li' " {\A height: @var;\A content: ' + ';\A}";white-space:pre}.test-content-calc{width:calc((100%/12*2) - 10px)}.test-svg-xml-image{background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" viewBox="0 0 38 40"><style>.st0{fill:none;stroke:%23ffffff;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;}</style><circle cx="14.7" cy="14.7" r="13.7" class="st0"/><path d="M23.9 24.7L37 39" class="st0"/></svg>') no-repeat left center} \ No newline at end of file +table>caption{margin-bottom:5px}table thead{background:#676056;color:#f7f3eb}table thead .headings{background:#807a6e}table thead a{color:#f7f3eb;display:block}table thead a label{color:#f7f3eb;cursor:pointer;display:block}table thead a:hover,table thead a:focus{color:#dac7a2;text-decoration:none}table tfoot{background:#f2ebde;color:#676056}table tfoot tr th,table tfoot tr td{text-align:left}table th{background:0 0;border:solid #cac3b4;border-width:0 1px;font-size:14px;padding:6px 10px;text-align:center}table td{border:solid #cac3b4;border-width:0 1px;padding:6px 10px 7px;vertical-align:top}table tbody tr td{background:#fff;color:#676056;padding-top:12px}table tbody tr td:first-child{border-left:0}table tbody tr td:first-child input[type=checkbox]{margin:0}table tbody tr td:last-child{border-right:0}table tbody tr:last-child th,table tbody tr:last-child td{border-bottom-width:1px}table tbody tr:nth-child(odd) td,table tbody tr:nth-child(odd) th{background-color:#f7f3eb}table tbody.even tr td{background:#fff}table tbody.odd tr td{background:#f7f3eb}table .dropdown-menu li{padding:7px 15px;line-height:14px;cursor:pointer}table .col-draggable .draggable-handle{float:left;position:relative;top:0}.not-sort{padding-right:10px}.sort-arrow-asc,.sort-arrow-desc{padding-right:10px;position:relative}.sort-arrow-asc:after,.sort-arrow-desc:after{right:-11px;top:-1px;position:absolute;width:23px}.sort-arrow-asc:hover:after,.sort-arrow-desc:hover:after{color:#dac7a2}.sort-arrow-asc{display:inline-block;text-decoration:none}.sort-arrow-asc:after{font-family:'icons-blank-theme';content:'\e626';font-size:13px;line-height:inherit;color:#f7f3eb;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.sort-arrow-asc:hover:after{color:#dac7a2}.sort-arrow-desc{display:inline-block;text-decoration:none}.sort-arrow-desc:after{font-family:'icons-blank-theme';content:'\e623';font-size:13px;line-height:inherit;color:#f7f3eb;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.sort-arrow-desc:hover:after{color:#dac7a2}.grid-actions .input-text,.pager .input-text,.massaction .input-text,.filter .input-text,.grid-actions select,.pager select,.massaction select,.filter select,.grid-actions .select,.pager .select,.massaction .select,.filter .select{border-color:#989287;box-shadow:none;border-radius:1px;height:28px;margin:0 10px 0 0}.filter th{border:0 solid #676056;padding:6px 3px;vertical-align:top}.filter .ui-datepicker-trigger{cursor:pointer;margin-top:2px}.filter .input-text{padding:0 5px}.filter .range-line:not(:last-child){margin-bottom:5px}.filter .date{padding-right:28px;position:relative;display:inline-block;text-decoration:none}.filter .date .hasDatepicker{vertical-align:top;width:99%}.filter .date img{cursor:pointer;height:25px;width:25px;right:0;position:absolute;vertical-align:middle;z-index:2;opacity:0}.filter .date:before{font-family:'icons-blank-theme';content:'\e612';font-size:42px;line-height:30px;color:#f7f3eb;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.filter .date:hover:before{color:#dac7a2}.filter .date:before{height:29px;margin-left:5px;position:absolute;right:-3px;top:-3px;width:35px}.filter select{border-color:#cac3b4;margin:0;padding:0;width:99%}.filter input.input-text{border-color:#cac3b4;margin:0;width:99%}.filter input.input-text::-webkit-input-placeholder{color:#989287 !important;text-transform:lowercase}.filter input.input-text::-moz-placeholder{color:#989287 !important;text-transform:lowercase}.filter input.input-text:-moz-placeholder{color:#989287 !important;text-transform:lowercase}.filter input.input-text:-ms-input-placeholder{color:#989287 !important;text-transform:lowercase}.grid{background:#fff;color:#676056;font-size:13px;font-weight:400;padding:15px}.grid table{width:100%}.grid tbody tr.selected th,.grid tbody tr.selected td,.grid tbody tr:hover th,.grid tbody tr:hover td,.grid tbody tr:nth-child(odd):hover th,.grid tbody tr:nth-child(odd):hover td{background-color:#f2ebde;cursor:pointer}.grid tbody tr.selected th.empty-text,.grid tbody tr.selected td.empty-text,.grid tbody tr:hover th.empty-text,.grid tbody tr:hover td.empty-text,.grid tbody tr:nth-child(odd):hover th.empty-text,.grid tbody tr:nth-child(odd):hover td.empty-text{background-color:#f7f3eb;cursor:default}.grid .empty-text{font:400 20px/1.2 'Open Sans',sans-serif;text-align:center;white-space:nowrap}.grid .col-sku{max-width:100px;width:100px}.grid .col-select,.grid .col-massaction{text-align:center}.grid .editable .input-text{width:65px}.grid .col-actions .action-select{background:#fff;border-color:#989287;height:28px;margin:0;padding:4px 4px 5px;width:80px}.grid .col-position.editable{white-space:nowrap}.grid .col-position.editable .input-text{margin:-7px 5px 0;width:70%}.eq-ie9 .hor-scroll{display:inline-block;min-height:0;overflow-y:hidden;overflow-x:auto;width:100%}.data-table{border-collapse:separate;width:100%}.data-table thead,.data-table tfoot,.data-table th,.accordion .config .data-table thead th,.accordion .config .data-table tfoot td,.accordion .config .accordion .config .data-table tfoot td th{background:#fff;color:#676056;font-size:13px;font-weight:600}.data-table th{text-align:left}.data-table thead th,.accordion .config .data-table thead th th,.accordion .config .data-table tfoot td th,.accordion .config .accordion .config .data-table tfoot td th th{border:solid #c9c2b8;border-width:0 0 1px;padding:7px}.data-table td,.data-table tbody tr th,.data-table tbody tr td,.accordion .config .data-table td{background:#fff;border-width:0;padding:5px 7px;vertical-align:middle}.data-table tbody tr:nth-child(odd) th,.data-table tbody tr:nth-child(odd) td,.accordion .config .data-table tbody tr:nth-child(odd) td{background:#fbfaf6}.data-table tbody.odd tr th,.data-table tbody.odd tr td{background:#fbfaf6}.data-table tbody.even tr th,.data-table tbody.even tr td{background:#fff}.data-table tfoot tr:last-child th,.data-table tfoot tr:last-child td,.data-table .accordion .config .data-table tfoot tr:last-child td{border:0}.data-table.order-tables tbody td{vertical-align:top}.data-table.order-tables tbody:hover tr th,.data-table.order-tables tbody:hover tr td{background:#f7f3eb}.data-table.order-tables tfoot td{background:#f2ebde;color:#676056;font-size:13px;font-weight:600}.data-table input[type=text]{width:98%;padding-left:1%;padding-right:1%}.data-table select{margin:0;box-sizing:border-box}.data-table .col-actions .actions-split{margin-top:4px}.data-table .col-actions .actions-split [class^=action-]{background:0 0;border:1px solid #c8c3b5;padding:3px 5px;color:#bbb3a6;font-size:12px}.data-table .col-actions .actions-split [class^=action-]:first-child{border-right:0}.data-table .col-actions .actions-split .dropdown-menu{margin-top:-1px}.data-table .col-actions .actions-split .dropdown-menu a{display:block;color:#333;text-decoration:none}.data-table .col-actions .actions-split.active .action-toggle{position:relative;border-bottom-right-radius:0;box-shadow:none;background:#fff}.data-table .col-actions .actions-split.active .action-toggle:after{position:absolute;top:100%;left:0;right:0;height:2px;margin-top:-1px;background:#fff;content:'';z-index:2}.data-table .col-actions .actions-split.active .action-toggle .dropdown-menu{border-top-right-radius:0}.data-table .col-default{white-space:nowrap;text-align:center;vertical-align:middle}.data-table .col-delete{text-align:center;width:32px}.data-table .col-file{white-space:nowrap}.data-table .col-file input,.data-table .col-file .input-text{margin:0 5px;width:40%}.data-table .col-file input:first-child,.data-table .col-file .input-text:first-child{margin-left:0}.data-table .col-actions-add{padding:10px 0}.grid-actions{background:#fff;font-size:13px;line-height:28px;padding:10px 15px;position:relative}.grid-actions+.grid{padding-top:5px}.grid-actions .export,.grid-actions .filter-actions{float:right;margin-left:10px;vertical-align:top}.grid-actions .import{display:block;vertical-align:top}.grid-actions .action-reset{background:0 0;border:0;display:inline;line-height:1.42857143;margin:0;padding:0;color:#1979c3;text-decoration:none;margin:6px 10px 0 0;vertical-align:top}.grid-actions .action-reset:visited{color:purple;text-decoration:none}.grid-actions .action-reset:hover{color:#006bb4;text-decoration:underline}.grid-actions .action-reset:active{color:#ff5501;text-decoration:underline}.grid-actions .action-reset:hover{color:#006bb4}.grid-actions .action-reset:hover,.grid-actions .action-reset:active,.grid-actions .action-reset:focus{background:0 0;border:0}.grid-actions .action-reset.disabled,.grid-actions .action-reset[disabled],fieldset[disabled] .grid-actions .action-reset{color:#1979c3;text-decoration:underline;cursor:default;pointer-events:none;opacity:.5}.grid-actions .import .label,.grid-actions .export .label,.massaction>.entry-edit .label{margin:0 14px 0 0;vertical-align:inherit}.grid-actions .import .action-,.grid-actions .export .action-,.grid-actions .filter-actions .action-,.massaction>.entry-edit .action-{vertical-align:inherit}.grid-actions .filter .date{float:left;margin:0 15px 0 0;position:relative}.grid-actions .filter .date:before{color:#676056;top:1px}.grid-actions .filter .date:hover:before{color:#31302b}.grid-actions .filter .label{margin:0}.grid-actions .filter .hasDatepicker{margin:0 5px;width:80px}.grid-actions .filter .show-by .select{margin-left:5px;padding:4px 4px 5px;vertical-align:top;width:auto}.grid-actions .filter.required:after{content:''}.grid-actions img{vertical-align:middle;height:22px;width:22px}.grid-actions .validation-advice{background:#f9d4d4;border:1px solid #e22626;border-radius:3px;color:#e22626;margin:5px 0 0;padding:3px 7px;position:absolute;white-space:nowrap;z-index:5}.grid-actions .validation-advice:before{width:0;height:0;border:5px solid transparent;border-bottom-color:#e22626;content:'';left:50%;margin-left:-5px;position:absolute;top:-11px}.grid-actions input[type=text].validation-failed{border-color:#e22626;box-shadow:0 0 8px rgba(226,38,38,.6)}.grid-actions .link-feed{white-space:nowrap}.pager{font-size:13px}.grid .pager{margin:15px 0 0;position:relative;text-align:center}.pager .pages-total-found{margin-right:25px}.pager .view-pages .select{margin:0 5px}.pager .link-feed{font-size:12px;margin:7px 15px 0 0;position:absolute;right:0;top:0}.pager .action-previous,.pager .action-next{background:0 0;border:0;display:inline;line-height:1.42857143;margin:0;padding:0;color:#1979c3;text-decoration:none;line-height:.6;overflow:hidden;width:20px}.pager .action-previous:visited,.pager .action-next:visited{color:purple;text-decoration:none}.pager .action-previous:hover,.pager .action-next:hover{color:#006bb4;text-decoration:underline}.pager .action-previous:active,.pager .action-next:active{color:#ff5501;text-decoration:underline}.pager .action-previous:hover,.pager .action-next:hover{color:#006bb4}.pager .action-previous:hover,.pager .action-next:hover,.pager .action-previous:active,.pager .action-next:active,.pager .action-previous:focus,.pager .action-next:focus{background:0 0;border:0}.pager .action-previous.disabled,.pager .action-next.disabled,.pager .action-previous[disabled],.pager .action-next[disabled],fieldset[disabled] .pager .action-previous,fieldset[disabled] .pager .action-next{color:#1979c3;text-decoration:underline;cursor:default;pointer-events:none;opacity:.5}.pager .action-previous:before,.pager .action-next:before{margin-left:-10px}.pager .action-previous.disabled,.pager .action-next.disabled{opacity:.3}.pager .action-previous{display:inline-block;text-decoration:none}.pager .action-previous>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.pager .action-previous>span.focusable:active,.pager .action-previous>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.pager .action-previous>span.focusable:active,.pager .action-previous>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.pager .action-previous:before{font-family:'icons-blank-theme';content:'\e617';font-size:40px;line-height:inherit;color:#026294;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.pager .action-previous:hover:before{color:#007dbd}.pager .action-next{display:inline-block;text-decoration:none}.pager .action-next>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.pager .action-next>span.focusable:active,.pager .action-next>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.pager .action-next>span.focusable:active,.pager .action-next>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.pager .action-next:before{font-family:'icons-blank-theme';content:'\e608';font-size:40px;line-height:inherit;color:#026294;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.pager .action-next:hover:before{color:#007dbd}.pager .input-text{height:25px;line-height:16px;margin-right:5px;text-align:center;width:25px;vertical-align:top}.pager .pages-total{line-height:25px;vertical-align:top}.massaction{background:#fff;border-top:1px solid #f2ebde;font-size:13px;line-height:28px;padding:15px 15px 0}.massaction>.entry-edit{float:right}.massaction>.entry-edit .field-row{display:inline-block;vertical-align:top}.massaction>.entry-edit .validation-advice{display:none !important}.massaction>.entry-edit .form-inline{display:inline-block}.massaction>.entry-edit .label{padding:0;width:auto}.massaction>.entry-edit .action-{vertical-align:top}.massaction .select.validation-failed{border:1px dashed #e22626;background:#f9d4d4}.grid-severity-critical,.grid-severity-major,.grid-severity-notice,.grid-severity-minor{background:#feeee1;border:1px solid #ed4f2e;color:#ed4f2e;display:block;padding:0 3px;font-weight:700;line-height:17px;text-transform:uppercase;text-align:center}.grid-severity-critical,.grid-severity-major{border-color:#e22626;background:#f9d4d4;color:#e22626}.grid-severity-notice{border-color:#5b8116;background:#d0e5a9;color:#185b00}.grid tbody td input[type=text],.data-table tbody td input[type=text],.grid tbody th input[type=text],.data-table tbody th input[type=text],.grid tbody td .input-text,.data-table tbody td .input-text,.grid tbody th .input-text,.data-table tbody th .input-text,.grid tbody td select,.data-table tbody td select,.grid tbody th select,.data-table tbody th select,.grid tbody td .select,.data-table tbody td .select,.grid tbody th .select,.data-table tbody th .select{width:99%}.ui-tabs-panel .grid .col-sku{max-width:150px;width:150px}.col-indexer_status,.col-indexer_mode{width:160px}.fieldset-wrapper .grid-actions+.grid{padding-top:15px}.fieldset-wrapper .grid-actions{padding:10px 0 0}.fieldset-wrapper .grid{padding:0}.fieldset-wrapper .massaction{padding:0;border-top:none;margin-bottom:15px}.accordion .grid{padding:0}.ui-dialog-content .grid-actions,.ui-dialog-content .grid{padding-left:0;padding-right:0}.qty-table td{border:0;padding:0 5px 3px}.sales-order-create-index .sales-order-create-index .grid table .action-configure{float:right}.sales-order-create-index .data-table .border td{padding-bottom:15px}.sales-order-create-index .actions.update{margin:10px 0}.adminhtml-order-shipment-new .grid .col-product{max-width:770px;width:770px}.customer-index-index .grid .col-name{max-width:90px;width:90px}.customer-index-index .grid .col-billing_region{width:70px}.adminhtml-cms-hierarchy-index .col-title,.adminhtml-cms-hierarchy-index .col-identifier{max-width:410px;width:410px}.adminhtml-widget-instance-edit .grid-chooser .control{margin-top:-19px;width:80%}.eq-ie9 .adminhtml-widget-instance-edit .grid-chooser .control{margin-top:-18px}.adminhtml-widget-instance-edit .grid-chooser .control .grid-actions{padding:0 0 15px}.adminhtml-widget-instance-edit .grid-chooser .control .grid{padding:0}.adminhtml-widget-instance-edit .grid-chooser .control .addon input:last-child,.adminhtml-widget-instance-edit .grid-chooser .control .addon select:last-child{border-radius:0}.reports-report-product-sold .grid .col-name{max-width:720px;width:720px}.adminhtml-system-store-index .grid td{max-width:310px}.adminhtml-system-currency-index .grid{padding-top:0}.adminhtml-system-currency-index .col-currency-edit-rate{min-width:40px}.adminhtml-system-currency-index .col-base-currency{font-weight:700}.adminhtml-system-currency-index .old-rate{display:block;margin-top:3px;text-align:center}.adminhtml-system-currency-index .hor-scroll{overflow-x:auto;min-width:970px}.adminhtml-system-currencysymbol-index .col-currency{width:35%}.adminhtml-system-currencysymbol-index .grid .input-text{margin:0 10px 0 0;width:50%}.catalog-product-set-index .col-set_name{max-width:930px;width:930px}.adminhtml-export-index .grid td{vertical-align:middle}.adminhtml-export-index .grid .input-text-range{margin:0 10px 0 5px;width:37%}.adminhtml-export-index .grid .input-text-range-date{margin:0 5px;width:32%}.adminhtml-export-index .ui-datepicker-trigger{display:inline-block;margin:-3px 10px 0 0;vertical-align:middle}.adminhtml-notification-index .grid .col-select,.adminhtml-cache-index .grid .col-select,.adminhtml-process-list .grid .col-select,.indexer-indexer-list .grid .col-select{width:10px}@font-face{font-family:'icons-blank-theme';src:url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2') format('woff2'),url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff') format('woff');font-weight:400;font-style:normal}@font-face{font-family:'icons-blank-theme';src:url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2') format('woff2'),url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff') format('woff');font-weight:400;font-style:normal}.navigation{background-color:#676056;position:relative;z-index:5}.navigation .level-0.reverse>.submenu{right:1px}.navigation>ul{position:relative;text-align:right}.navigation .level-0>.submenu{display:none;position:absolute;top:100%;padding:19px 13px}.navigation .level-0>.submenu a{display:block;color:#676056;font-size:13px;font-weight:400;line-height:1.385;padding:3px 12px 3px;text-decoration:none}.navigation .level-0>.submenu a:focus,.navigation .level-0>.submenu a:hover{text-decoration:underline}.navigation .level-0>.submenu a:hover{color:#fff;background:#989287;text-decoration:none}.navigation .level-0>.submenu li{margin-bottom:1px}.navigation .level-0>.submenu a[href="#"]{cursor:default;display:block;color:#676056;font-size:14px;font-weight:700;line-height:1;margin:7px 0 6px;padding:0 12px}.navigation .level-0>.submenu a[href="#"]:focus,.navigation .level-0>.submenu a[href="#"]:hover{color:#676056;font-size:14px;font-weight:700;background:0 0;text-decoration:none}.navigation .level-0{display:inline-block;float:left;text-align:left;transition:display .15s ease-out}.navigation .level-0>a{background:0 0;display:block;padding:12px 13px 0;color:#f2ebde;font-size:13px;font-weight:600;text-transform:uppercase;text-decoration:none;transition:background .15s ease-out}.navigation .level-0>a:after{content:"";display:block;margin-top:10px;height:3px;font-size:0}.navigation .level-0.active>a{font-weight:700}.navigation .level-0.active>a:after{background:#ef672f}.navigation .level-0.hover.recent>a{background:#fff;color:#676056;font-size:13px;font-weight:600}.navigation .level-0.hover.recent>a:after{background:0 0}.navigation .level-0.hover.recent.active>a{font-weight:700}.navigation .level-0>.submenu{opacity:0;visibility:hidden}.navigation .level-0.recent.hover>.submenu{opacity:1;visibility:visible}.no-js .navigation .level-0:hover>.submenu,.no-js .navigation .level-0.hover>.submenu,.no-js .navigation .level-0>a:focus+.submenu{display:block}.navigation .level-0>.submenu{background:#fff;box-shadow:0 3px 3px rgba(50,50,50,.15)}.navigation .level-0>.submenu li{max-width:200px}.navigation .level-0>.submenu>ul{white-space:nowrap}.navigation .level-0>.submenu .column{display:inline-block;margin-left:40px;vertical-align:top}.navigation .level-0>.submenu .column:first-child{margin-left:0}.navigation .level-0 .submenu .level-1{white-space:normal}.navigation .level-0.parent .submenu .level-1.parent{margin:17px 0 25px}.navigation .level-0.parent .level-1.parent:first-child{margin-top:0}.navigation .level-2 .submenu{margin-left:7px}.navigation .level-0>.submenu .level-2>a[href="#"]{font-size:13px;margin-top:10px;margin-left:7px}.navigation .level-2>.submenu a{font-size:12px;line-height:1.231}.navigation .level-0>.submenu .level-3>a[href="#"],.navigation .level-3 .submenu{margin-left:15px}.navigation .level-0.item-system,.navigation .level-0.item-stores{float:none}.navigation .level-0.item-system>.submenu,.navigation .level-0.item-stores>.submenu{left:auto;right:1px}.adminhtml-dashboard-index .col-1-layout{max-width:1300px;border:none;border-radius:0;padding:0;background:#f7f3eb}.dashboard-inner{padding-top:35px}.dashboard-inner:before,.dashboard-inner:after{content:"";display:table}.dashboard-inner:after{clear:both}.dashboard-inner:before,.dashboard-inner:after{content:"";display:table}.dashboard-inner:after{clear:both}.dashboard-secondary{float:left;width:32%;margin:0 1.5%}.dashboard-main{float:right;width:65%}.dashboard-diagram-chart{max-width:100%;height:auto}.dashboard-diagram-nodata,.dashboard-diagram-switcher{padding:20px 0}.dashboard-diagram-image{background:#fff url(../mui/images/ajax-loader-small.gif) no-repeat 50% 50%}.dashboard-container .ui-tabs-panel{background-color:#fff;min-height:40px;padding:15px}.dashboard-store-stats{margin-top:35px}.dashboard-store-stats .ui-tabs-panel{background:#fff url(../mui/images/ajax-loader-small.gif) no-repeat 50% 50%}.dashboard-item{margin-bottom:30px}.dashboard-item-header{margin-left:5px}.dashboard-item.dashboard-item-primary{margin-bottom:35px}.dashboard-item.dashboard-item-primary .title{font-size:22px;margin-bottom:5px}.dashboard-item.dashboard-item-primary .dashboard-sales-value{display:block;text-align:right;font-weight:600;font-size:30px;margin-right:12px;padding-bottom:5px}.dashboard-item.dashboard-item-primary:first-child{color:#ef672f}.dashboard-item.dashboard-item-primary:first-child .title{color:#ef672f}.dashboard-totals{background:#fff;padding:50px 15px 25px}.dashboard-totals-list{margin:0;padding:0;list-style:none none}.dashboard-totals-list:before,.dashboard-totals-list:after{content:"";display:table}.dashboard-totals-list:after{clear:both}.dashboard-totals-list:before,.dashboard-totals-list:after{content:"";display:table}.dashboard-totals-list:after{clear:both}.dashboard-totals-item{float:left;width:18%;margin-left:7%;padding-top:15px;border-top:2px solid #cac3b4}.dashboard-totals-item:first-child{margin-left:0}.dashboard-totals-label{display:block;font-size:16px;font-weight:600;padding-bottom:2px}.dashboard-totals-value{color:#ef672f;font-size:20px}.dashboard-data{width:100%}.dashboard-data thead{background:0 0}.dashboard-data thead tr{background:0 0}.dashboard-data th,.dashboard-data td{border:none;padding:10px 12px;text-align:right}.dashboard-data th:first-child,.dashboard-data td:first-child{text-align:left}.dashboard-data th{color:#676056;font-weight:600}.dashboard-data td{background-color:transparent}.dashboard-data tbody tr:hover td{background-color:transparent}.dashboard-data tbody tr:nth-child(odd) td,.dashboard-data tbody tr:nth-child(odd):hover td,.dashboard-data tbody tr:nth-child(odd) th,.dashboard-data tbody tr:nth-child(odd):hover th{background-color:#e1dbcf}.ui-tabs-panel .dashboard-data tbody tr:nth-child(odd) td,.ui-tabs-panel .dashboard-data tbody tr:nth-child(odd):hover td,.ui-tabs-panel .dashboard-data tbody tr:nth-child(odd) th,.ui-tabs-panel .dashboard-data tbody tr:nth-child(odd):hover th{background-color:#f7f3eb}.dashboard-data td.empty-text{text-align:center}.ui-tabs-panel .dashboard-data{background-color:#fff}.mage-dropdown-dialog.ui-dialog .ui-dialog-content{overflow:visible}.mage-dropdown-dialog.ui-dialog .ui-dialog-buttonpane{padding:0}.message-system-inner{background:#f7f3eb;border:1px solid #c0bbaf;border-top:0;border-radius:0 0 5px 5px;float:right;overflow:hidden}.message-system-unread .message-system-inner{float:none}.message-system-list{margin:0;padding:0;list-style:none;float:left}.message-system .message-system-list{width:75%}.message-system-list li{padding:5px 13px 7px 36px;position:relative}.message-system-short{padding:5px 13px 7px;float:right}.message-system-short span{display:inline-block;margin-left:7px;border-left:1px #d1ccc3 solid}.message-system-short span:first-child{border:0;margin-left:0}.message-system-short a{padding-left:27px;position:relative;height:16px}.message-system .message-system-short a:before,.message-system-list li:before{font-family:'MUI-Icons';font-style:normal;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;height:16px;width:16px;font-size:16px;line-height:16px;text-align:center;position:absolute;left:7px;top:2px}.message-system-list li:before{top:5px;left:13px}.message-system .message-system-short .warning a:before,.message-system-list li.warning:before{content:"\e006";color:#f2a825}.message-system .message-system-short .error a:before,.message-system-list li.error:before{content:"\e086";font-family:'MUI-Icons';color:#c00815}.ui-dialog .message-system-list{margin-bottom:25px}.sales-order-create-index .order-errors .notice{color:#ed4f2e;font-size:11px;margin:5px 0 0}.order-errors .fieldset-wrapper-title .title{box-sizing:border-box;background:#fffbf0;border:1px solid #d87e34;border-radius:5px;color:#676056;font-size:14px;margin:20px 0;padding:10px 26px 10px 35px;position:relative}.order-errors .fieldset-wrapper-title .title:before{position:absolute;left:11px;top:50%;margin-top:-11px;width:auto;height:auto;font-family:'MUI-Icons';font-style:normal;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;font-size:16px;line-height:inherit;content:'\e046';color:#d87e34}.search-global.miniform{position:relative;z-index:1000;display:inline-block;vertical-align:top;margin:6px 10px 0}.search-global.miniform .mage-suggest{border:0;border-radius:0}.search-global-actions{display:none}.search-global-field{margin:0}.search-global-field .label{position:absolute;right:4px;z-index:2;cursor:pointer;display:inline-block;text-decoration:none}.search-global-field .label>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.search-global-field .label>span.focusable:active,.search-global-field .label>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.search-global-field .label>span.focusable:active,.search-global-field .label>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.search-global-field .label:before{font-family:'MUI-Icons';content:"\e01f";font-size:18px;line-height:29px;color:#cac3b4;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.search-global-field .control{width:48px;overflow:hidden;opacity:0;transition:all .3s ease}.search-global-field .control input[type=text]{background:0 0;border:none;width:100%}.search-global-field.active{z-index:2}.search-global-field.active .label:before{display:none}.search-global-field.active .control{overflow:visible;opacity:1;transition:all .3s ease;width:300px}.search-global-menu{box-sizing:border-box;display:block;width:100%}.notifications-summary{display:inline-block;text-align:left;position:relative;z-index:1}.notifications-summary.active{z-index:999}.notifications-action{color:#f2ebde;padding:12px 22px 11px;text-transform:capitalize;display:inline-block;text-decoration:none}.notifications-action:before{font-family:"MUI-Icons";content:"\e06e";font-size:18px;line-height:18px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.notifications-action:visited,.notifications-action:focus,.notifications-action:active,.notifications-action:hover{color:#f2ebde;text-decoration:none}.notifications-action.active{background-color:#fff;color:#676056}.notifications-action .text{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.notifications-action .text.focusable:active,.notifications-action .text.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-action .text.focusable:active,.notifications-action .text.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-action .qty.counter{display:inline-block;background:#ed4f2e;color:#f2ebde;font-size:12px;line-height:12px;font-weight:700;padding:1px 3px;position:absolute;top:6px;left:50%;border-radius:4px}.notifications-list{width:300px;padding:0;margin:0}.notifications-list .last{padding:10px;text-align:center;font-size:12px}.notifications-summary .notifications-entry{padding:15px;color:#676056;font-size:11px;font-weight:400}.notifications-entry{position:relative;z-index:1}.notifications-entry:hover .action{display:block}.notifications-entry-title{padding-right:15px;color:#ed4f2e;font-size:12px;font-weight:600;display:block;margin-bottom:10px}.notifications-entry-description{line-height:1.3;display:block;max-height:3.9em;overflow:hidden;margin-bottom:10px;text-overflow:ellipsis}.notifications-close.action{position:absolute;z-index:1;top:12px;right:12px;display:inline-block;background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400;display:none}.notifications-close.action>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.notifications-close.action>span.focusable:active,.notifications-close.action>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-close.action>span.focusable:active,.notifications-close.action>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-close.action:before{font-family:'MUI-Icons';content:"\e07f";font-size:16px;line-height:inherit;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.notifications-close.action:focus,.notifications-close.action:active{background:0 0;border:none}.notifications-close.action:hover{background:0 0;border:none}.notifications-close.action.disabled,.notifications-close.action[disabled],fieldset[disabled] .notifications-close.action{cursor:not-allowed;pointer-events:none;opacity:.5}.notifications-dialog-content{display:none}.notifications-critical .notifications-entry-title{padding-left:25px;display:inline-block;text-decoration:none}.notifications-critical .notifications-entry-title:before{font-family:'MUI-Icons';content:"\e086";font-size:18px;line-height:18px;color:#c00815;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.notifications-critical .notifications-entry-title:before{position:absolute;margin-left:-25px}.notifications-dialog-content .notifications-entry-time{color:#8c867e;font-size:13px;font-family:Helvetica,Arial,sans-serif;position:absolute;right:17px;bottom:27px;text-align:right}.notifications-url{display:inline-block;text-decoration:none}.notifications-url>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.notifications-url>span.focusable:active,.notifications-url>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-url>span.focusable:active,.notifications-url>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.notifications-url:after{font-family:'MUI-Icons';content:"\e084";font-size:16px;line-height:inherit;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center;margin:-2px 0 0 10px}.notifications-dialog-content .notifications-entry-title{font-size:15px}.locale-switcher-field{white-space:nowrap;float:left}.locale-switcher-field .control,.locale-switcher-field .label{vertical-align:middle;margin:0 10px 0 0;display:inline-block}.locale-switcher-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;border:1px solid #ada89e;max-width:200px;height:31px;background:url("../images/select-bg.svg") no-repeat 100% 50%;background-size:30px 60px;padding-right:29px;text-indent:.01px;text-overflow:''}.locale-switcher-select::-ms-expand{display:none}.lt-ie10 .locale-switcher-select{background-image:none;padding-right:4px}@-moz-document url-prefix(){.locale-switcher-select{background-image:none}}@-moz-document url-prefix(){.locale-switcher-select{background-image:none}}.mage-suggest{text-align:left;box-sizing:border-box;position:relative;display:inline-block;vertical-align:top;width:100%;background-color:#fff;border:1px solid #ada89e;border-radius:2px}.mage-suggest:after{position:absolute;top:3px;right:3px;bottom:0;width:22px;text-align:center;font-family:'MUI-Icons';font-style:normal;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;content:'\e01f';font-size:18px;color:#b2b2b2}.mage-suggest input[type=search],.mage-suggest input.search{width:100%;border:none;background:0 0;padding-right:30px}.mage-suggest.category-select input[type=search],.mage-suggest.category-select input.search{height:26px}.mage-suggest-dropdown{position:absolute;left:0;right:0;top:100%;margin:1px -1px 0;border:1px solid #cac2b5;background:#fff;box-shadow:0 2px 4px rgba(0,0,0,.2);z-index:990}.mage-suggest-dropdown ul{margin:0;padding:0;list-style:none}.mage-suggest-dropdown li{border-bottom:1px solid #e5e5e5;padding:0}.mage-suggest-dropdown li a{display:block}.mage-suggest-dropdown li a.ui-state-focus{background:#f5f5f5}.mage-suggest-dropdown li a,.mage-suggest-dropdown .jstree li a:hover,.mage-suggest-dropdown .jstree .jstree-hovered,.mage-suggest-dropdown .jstree .jstree-clicked{padding:6px 12px 5px;text-decoration:none;color:#333}.mage-suggest-dropdown .jstree li a:hover,.mage-suggest-dropdown .jstree .jstree-hovered,.mage-suggest-dropdown .jstree .jstree-clicked{border:none}.mage-suggest-dropdown .jstree li{border-bottom:0}.mage-suggest-dropdown .jstree li a{display:inline-block}.mage-suggest-dropdown .jstree .mage-suggest-selected>a{color:#000;background:#f1ffeb}.field-category_ids .mage-suggest-dropdown,.field-new_category_parent .mage-suggest-dropdown{max-height:200px;overflow:auto}.mage-suggest-dropdown .jstree .mage-suggest-selected>a:hover,.mage-suggest-dropdown .jstree .mage-suggest-selected>.jstree-hovered,.mage-suggest-dropdown .jstree .mage-suggest-selected>.jstree-clicked,.mage-suggest-dropdown .jstree .mage-suggest-selected.mage-suggest-not-active>.jstree-hovered,.mage-suggest-dropdown .jstree .mage-suggest-selected.mage-suggest-not-active>.jstree-clicked{background:#e5ffd9}.mage-suggest-dropdown .jstree .mage-suggest-not-active>a{color:#d4d4d4}.mage-suggest-dropdown .jstree .mage-suggest-not-active>a:hover,.mage-suggest-dropdown .jstree .mage-suggest-not-active>.jstree-hovered,.mage-suggest-dropdown .jstree .mage-suggest-not-active>.jstree-clicked{background:#f5f5f5}.mage-suggest-dropdown .category-path{font-size:11px;margin-left:10px;color:#9ba8b5}.suggest-expandable .action-dropdown .action-toggle{display:inline-block;max-width:500px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:0 0;border:none;box-shadow:none;color:#676056;font-size:12px;padding:5px 4px;filter:none}.suggest-expandable .action-dropdown .action-toggle span{display:inline}.suggest-expandable .action-dropdown .action-toggle:before{display:inline-block;float:right;margin-left:4px;font-size:13px;color:#b2b0ad}.suggest-expandable .action-dropdown .action-toggle:hover:before{color:#7e7e7e}.suggest-expandable .dropdown-menu{margin:1px 0 0;left:0;right:auto;width:245px;z-index:4}.suggest-expandable .mage-suggest{border:none;border-radius:3px 3px 0 0}.suggest-expandable .mage-suggest:after{top:10px;right:8px}.suggest-expandable .mage-suggest-inner .title{margin:0;padding:0 10px 4px;text-transform:uppercase;color:#a6a098;font-size:12px;border-bottom:1px solid #e5e5e5}.suggest-expandable .mage-suggest-inner>input[type=search],.suggest-expandable .mage-suggest-inner>input.search{position:relative;margin:6px 5px 5px;padding-right:20px;border:1px solid #ada89e;width:236px;z-index:1}.suggest-expandable .mage-suggest-inner>input.ui-autocomplete-loading,.suggest-expandable .mage-suggest-inner>input.mage-suggest-state-loading{background:#fff url("../mui/images/ajax-loader-small.gif") no-repeat 190px 50%}.suggest-expandable .mage-suggest-dropdown{margin-top:0;border-top:0;border-radius:0 0 3px 3px;max-height:300px;overflow:auto;width:100%;float:left}.suggest-expandable .mage-suggest-dropdown ul{margin:0;padding:0;list-style:none}.suggest-expandable .action-show-all:hover,.suggest-expandable .action-show-all:active,.suggest-expandable .action-show-all:focus,.suggest-expandable .action-show-all[disabled]{border-top:1px solid #e5e5e5;display:block;width:100%;padding:8px 10px 10px;text-align:left;font:12px/1.333 Arial,Verdana,sans-serif;color:#676056}.product-actions .suggest-expandable{max-width:500px;float:left;margin-top:1px}.page-actions.fixed #product-template-suggest-container{display:none}.catalog-category-edit .col-2-left-layout:before{display:none}.category-content .ui-tabs-panel .fieldset{padding-top:40px}.category-content .ui-tabs-panel .fieldset .legend{display:none}.attributes-edit-form .field:not(.field-weight) .addon{display:block;position:relative}.attributes-edit-form .field:not(.field-weight) .addon input[type=text]{border-width:1px}.attributes-edit-form .field:not(.field-weight) .addon .addafter{display:block;border:0;height:auto;width:auto}.attributes-edit-form .field:not(.field-weight) .addon input:focus~.addafter{box-shadow:none}.attributes-edit-form .with-addon .textarea{margin:0}.attributes-edit-form .attribute-change-checkbox{display:block;margin-top:5px}.attributes-edit-form .attribute-change-checkbox .label{float:none;padding:0;width:auto}.attributes-edit-form .attribute-change-checkbox .checkbox{margin-right:5px;width:auto}.attributes-edit-form .field-price .addon>input,.attributes-edit-form .field-special_price .addon>input,.attributes-edit-form .field-gift_wrapping_price .addon>input,.attributes-edit-form .field-msrp .addon>input,.attributes-edit-form .field-gift_wrapping_price .addon>input{padding-left:23px}.attributes-edit-form .field-price .addafter>strong,.attributes-edit-form .field-special_price .addafter>strong,.attributes-edit-form .field-gift_wrapping_price .addafter>strong,.attributes-edit-form .field-msrp .addafter>strong,.attributes-edit-form .field-gift_wrapping_price .addafter>strong{left:5px;position:absolute;top:3px}.attributes-edit-form .field.type-price input:focus+label,.attributes-edit-form .field-price input:focus+label,.attributes-edit-form .field-special_price input:focus+label,.attributes-edit-form .field-msrp input:focus+label,.attributes-edit-form .field-weight input:focus+label{box-shadow:none}.attributes-edit-form .field-special_from_date>.control .input-text,.attributes-edit-form .field-special_to_date>.control .input-text,.attributes-edit-form .field-news_from_date>.control .input-text,.attributes-edit-form .field-news_to_date>.control .input-text,.attributes-edit-form .field-custom_design_from>.control .input-text,.attributes-edit-form .field-custom_design_to>.control .input-text{border-width:1px;width:130px}.attributes-edit-form .field-weight .fields-group-2 .control{padding-right:27px}.attributes-edit-form .field-weight .fields-group-2 .control .addafter+.addafter{border-width:1px 1px 1px 0;border-style:solid;height:28px;right:0;position:absolute;top:0}.attributes-edit-form .field-weight .fields-group-2 .control .addafter strong{line-height:28px}.attributes-edit-form .field-weight .fields-group-2 .control>input:focus+.addafter+.addafter{box-shadow:0 0 8px rgba(82,168,236,.6)}.attributes-edit-form .field-gift_message_available .addon>input[type=checkbox],.attributes-edit-form .field-gift_wrapping_available .addon>input[type=checkbox]{width:auto;margin-right:5px}.attributes-edit-form .fieldset>.addafter{display:none}.advanced-inventory-edit .field.choice{display:block;margin:3px 0 0}.advanced-inventory-edit .field.choice .label{padding-top:1px}.product-actions:before,.product-actions:after{content:"";display:table}.product-actions:after{clear:both}.product-actions:before,.product-actions:after{content:"";display:table}.product-actions:after{clear:both}.product-actions .switcher{float:right}#configurable-attributes-container .actions-select{display:inline-block;position:relative}#configurable-attributes-container .actions-select:before,#configurable-attributes-container .actions-select:after{content:"";display:table}#configurable-attributes-container .actions-select:after{clear:both}#configurable-attributes-container .actions-select:before,#configurable-attributes-container .actions-select:after{content:"";display:table}#configurable-attributes-container .actions-select:after{clear:both}#configurable-attributes-container .actions-select .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}#configurable-attributes-container .actions-select .action.toggle:after{font-family:'icons-blank-theme';content:'\e607';font-size:22px;line-height:22px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}#configurable-attributes-container .actions-select .action.toggle:hover:after{color:inherit}#configurable-attributes-container .actions-select .action.toggle:active:after{color:inherit}#configurable-attributes-container .actions-select .action.toggle.active{display:inline-block;text-decoration:none}#configurable-attributes-container .actions-select .action.toggle.active:after{font-family:'icons-blank-theme';content:'\e618';font-size:22px;line-height:22px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}#configurable-attributes-container .actions-select .action.toggle.active:hover:after{color:inherit}#configurable-attributes-container .actions-select .action.toggle.active:active:after{color:inherit}#configurable-attributes-container .actions-select ul.dropdown{margin:0;padding:0;list-style:none none;box-sizing:border-box;background:#fff;border:1px solid #bbb;position:absolute;z-index:100;top:100%;min-width:100%;margin-top:4px;display:none;box-shadow:0 3px 3px rgba(0,0,0,.15)}#configurable-attributes-container .actions-select ul.dropdown li{margin:0;padding:3px 5px}#configurable-attributes-container .actions-select ul.dropdown li:hover{background:#e8e8e8;cursor:pointer}#configurable-attributes-container .actions-select.active{overflow:visible}#configurable-attributes-container .actions-select.active ul.dropdown{display:block}#configurable-attributes-container .actions-select .action.toggle{padding:1px 8px;border:1px solid #ada89e;background:#fff;border-radius:0 2px 2px 0}#configurable-attributes-container .actions-select .action.toggle:after{width:14px;text-indent:-2px}#configurable-attributes-container .actions-select ul.dropdown li:hover{background:#eef8fc}#configurable-attributes-container .actions-select ul.dropdown a{color:#333;text-decoration:none}#product-variations-matrix .actions-image-uploader{display:inline-block;position:relative;display:block;width:50px}#product-variations-matrix .actions-image-uploader:before,#product-variations-matrix .actions-image-uploader:after{content:"";display:table}#product-variations-matrix .actions-image-uploader:after{clear:both}#product-variations-matrix .actions-image-uploader:before,#product-variations-matrix .actions-image-uploader:after{content:"";display:table}#product-variations-matrix .actions-image-uploader:after{clear:both}#product-variations-matrix .actions-image-uploader .action.split{float:left;margin:0}#product-variations-matrix .actions-image-uploader .action.toggle{float:right;margin:0}#product-variations-matrix .actions-image-uploader .action.toggle{padding:6px 5px;display:inline-block;text-decoration:none}#product-variations-matrix .actions-image-uploader .action.toggle>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}#product-variations-matrix .actions-image-uploader .action.toggle>span.focusable:active,#product-variations-matrix .actions-image-uploader .action.toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}#product-variations-matrix .actions-image-uploader .action.toggle>span.focusable:active,#product-variations-matrix .actions-image-uploader .action.toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}#product-variations-matrix .actions-image-uploader .action.toggle:after{font-family:'icons-blank-theme';content:'\e607';font-size:22px;line-height:14px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}#product-variations-matrix .actions-image-uploader .action.toggle:hover:after{color:inherit}#product-variations-matrix .actions-image-uploader .action.toggle:active:after{color:inherit}#product-variations-matrix .actions-image-uploader .action.toggle.active{display:inline-block;text-decoration:none}#product-variations-matrix .actions-image-uploader .action.toggle.active>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}#product-variations-matrix .actions-image-uploader .action.toggle.active>span.focusable:active,#product-variations-matrix .actions-image-uploader .action.toggle.active>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}#product-variations-matrix .actions-image-uploader .action.toggle.active>span.focusable:active,#product-variations-matrix .actions-image-uploader .action.toggle.active>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}#product-variations-matrix .actions-image-uploader .action.toggle.active:after{font-family:'icons-blank-theme';content:'\e618';font-size:22px;line-height:14px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}#product-variations-matrix .actions-image-uploader .action.toggle.active:hover:after{color:inherit}#product-variations-matrix .actions-image-uploader .action.toggle.active:active:after{color:inherit}#product-variations-matrix .actions-image-uploader ul.dropdown{margin:0;padding:0;list-style:none none;box-sizing:border-box;background:#fff;border:1px solid #bbb;position:absolute;z-index:100;top:100%;min-width:100%;margin-top:4px;display:none;box-shadow:0 3px 3px rgba(0,0,0,.15)}#product-variations-matrix .actions-image-uploader ul.dropdown li{margin:0;padding:3px 5px}#product-variations-matrix .actions-image-uploader ul.dropdown li:hover{background:#e8e8e8;cursor:pointer}#product-variations-matrix .actions-image-uploader.active{overflow:visible}#product-variations-matrix .actions-image-uploader.active ul.dropdown{display:block}#product-variations-matrix .actions-image-uploader .action.toggle{padding:0 2px;border:1px solid #b7b2a7;background:#fff;border-radius:0 4px 4px 0;border-left:none;height:33px}#product-variations-matrix .actions-image-uploader .action.toggle.no-display{display:none}#product-variations-matrix .actions-image-uploader .action.toggle:after{width:12px;text-indent:-5px}#product-variations-matrix .actions-image-uploader ul.dropdown{left:0;margin-left:0;width:100px}#product-variations-matrix .actions-image-uploader ul.dropdown li:hover{background:#eef8fc}#product-variations-matrix .actions-image-uploader ul.dropdown a{color:#333;text-decoration:none}.debugging-hints .page-actions{position:relative;z-index:1}.debugging-hints .page-actions .debugging-hint-template-file{left:auto !important;right:0 !important}.filter-segments{list-style:none;padding:0}.adminhtml-report-customer-test-detail .col-id{width:35px}.adminhtml-report-customer-test-detail .col-period{white-space:nowrap;width:70px}.adminhtml-report-customer-test-detail .col-zip{width:50px}.adminhtml-report-customer-test-segment .col-id{width:35px}.adminhtml-report-customer-test-segment .col-status{width:65px}.adminhtml-report-customer-test-segment .col-qty{width:145px}.adminhtml-report-customer-test-segment .col-segment,.adminhtml-report-customer-test-segment .col-website{width:35%}.adminhtml-report-customer-test-segment .col-select{width:45px}.test-custom-attributes{margin-bottom:20px}.adminhtml-test-index th.col-id{text-align:left}.adminhtml-test-index .col-price{text-align:right;width:50px}.adminhtml-test-index .col-actions{width:50px}.adminhtml-test-index .col-select{width:60px}.adminhtml-test-edit .field-image .control{line-height:28px}.adminhtml-test-edit .field-image a{display:inline-block;margin:0 5px 0 0}.adminhtml-test-edit .field-image img{vertical-align:middle}.adminhtml-test-new .field-image .input-file,.adminhtml-test-edit .field-image .input-file{display:inline-block;margin:0 15px 0 0;width:auto}.adminhtml-test-new .field-image .addafter,.adminhtml-test-edit .field-image .addafter{border:0;box-shadow:none;display:inline-block;margin:0 15px 0 0;height:auto;width:auto}.adminhtml-test-new .field-image .delete-image,.adminhtml-test-edit .field-image .delete-image{display:inline-block;white-space:nowrap}.adminhtml-test-edit .field-image .delete-image input{margin:-3px 5px 0 0;width:auto;display:inline-block}.adminhtml-test-edit .field-image .addon .delete-image input:focus+label{border:0;box-shadow:none}.adminhtml-test-index .col-id{width:35px}.adminhtml-test-index .col-status{white-space:normal;width:75px}.adminhtml-test-index .col-websites{white-space:nowrap;width:200px}.adminhtml-test-index .col-price .label{display:inline-block;min-width:60px;white-space:nowrap}.adminhtml-test-index .col-price .price-excl-tax .price,.adminhtml-test-index .col-price .price-incl-tax .price{font-weight:700}.invitee_information,.inviter_information{width:48.9362%}.invitee_information{float:left}.inviter_information{float:right}.test_information .data-table th,.invitee_information .data-table th,.inviter_information .data-table th{width:20%;white-space:nowrap}.test_information .data-table textarea,.test_information .data-table input{width:100%}.tests-history ul{margin:0;padding-left:25px}.tests-history ul .status:before{display:inline-block;content:"|";margin:0 10px}.adminhtml-report-test-order .col-period{white-space:nowrap;width:70px}.adminhtml-report-test-order .col-inv-sent,.adminhtml-report-test-order .col-inv-acc,.adminhtml-report-test-order .col-acc,.adminhtml-report-test-order .col-rate{text-align:right;width:23%}.adminhtml-report-test-customer .col-id{width:35px}.adminhtml-report-test-customer .col-period{white-space:nowrap;width:70px}.adminhtml-report-test-customer .col-inv-sent,.adminhtml-report-test-customer .col-inv-acc{text-align:right;width:120px}.adminhtml-report-test-index .col-period{white-space:nowrap}.adminhtml-report-test-index .col-inv-sent,.adminhtml-report-test-index .col-inv-acc,.adminhtml-report-test-index .col-inv-disc,.adminhtml-report-test-index .col-inv-acc-rate,.adminhtml-report-test-index .col-inv-disc-rate{text-align:right;width:19%}.test_information .data-table,.invitee_information .data-table,.inviter_information .data-table{width:100%}.test_information .data-table tbody tr th,.invitee_information .data-table tbody tr th,.inviter_information .data-table tbody tr th{font-weight:700}.test_information .data-table tbody tr td,.test_information .data-table tbody tr th,.invitee_information .data-table tbody tr td,.invitee_information .data-table tbody tr th,.inviter_information .data-table tbody tr td,.inviter_information .data-table tbody tr th{background-color:#fff;border:0;padding:9px 10px 10px;color:#666;vertical-align:top}.test_information .data-table tbody tr:nth-child(2n+1) td,.test_information .data-table tbody tr:nth-child(2n+1) th,.invitee_information .data-table tbody tr:nth-child(2n+1) td,.invitee_information .data-table tbody tr:nth-child(2n+1) th,.inviter_information .data-table tbody tr:nth-child(2n+1) td,.inviter_information .data-table tbody tr:nth-child(2n+1) th{background-color:#fbfaf6}[class^=" adminhtml-test-"] .fieldset-wrapper-content .data-table .col-sort-order{width:80px}[class^=" adminhtml-test-"] .fieldset-wrapper-content .data-table td,[class^=" adminhtml-test-"] .fieldset-wrapper-content .accordion .config .data-table td{vertical-align:top}[class^=" adminhtml-test-"] .fieldset-wrapper-content .data-table td select,[class^=" adminhtml-test-"] .fieldset-wrapper-content .accordion .config .data-table td select{display:block;width:100%}[class^=" adminhtml-test-"] .fieldset-wrapper-content .data-table td .input-radio.global-scope,[class^=" adminhtml-test-"] .fieldset-wrapper-content .accordion .config .data-table td .input-radio.global-scope{margin-top:9px}.sales-order-create-index .ui-dialog .content>.test .field.text .input-text{width:100%}.sales-order-create-index .ui-dialog .content>.test .note .price{font-weight:600}.sales-order-create-index .ui-dialog .content>.test .note .price:before{content:": "}.sales-order-create-index .ui-dialog .content>.test .fixed.amount .label:after{content:": "}.sales-order-create-index .ui-dialog .content>.test .fixed.amount .control{display:inline-block;font-weight:600}.sales-order-create-index .ui-dialog .content>.test .fixed.amount .control .control-value{margin:-2px 0 0;padding:0}.eq-ie9 [class^=" adminhtml-test-"] .custom-options .data-table{word-wrap:normal;table-layout:auto}.rma-items .col-actions a.disabled,.newRma .col-actions a.disabled{cursor:default;opacity:.5}.rma-items .col-actions a.disabled:hover,.newRma .col-actions a.disabled:hover{text-decoration:none}.block.mselect-list .mselect-input{width:100%}.block.mselect-list .mselect-input-container .mselect-save{top:4px}.block.mselect-list .mselect-input-container .mselect-cancel{top:4px}html{font-size:62.5%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;font-size-adjust:100%}body,html{height:100%;min-height:100%}body{color:#676056;font-family:'Open Sans',sans-serif;line-height:1.33;font-weight:400;font-size:1.4rem;background:#f2ebde;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}body>*{-webkit-flex-grow:0;flex-grow:0;-webkit-flex-shrink:0;flex-shrink:0;-webkit-flex-basis:auto;flex-basis:auto}.page-wrapper{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;min-height:100%;width:100%;max-width:100%;min-width:990px}.page-wrapper>*{-webkit-flex-grow:0;flex-grow:0;-webkit-flex-shrink:0;flex-shrink:0;-webkit-flex-basis:auto;flex-basis:auto}.page-header{text-align:right}.page-header-wrapper{background-color:#31302b}.page-header:after{content:"";display:table;clear:both}.page-header .logo{margin-top:5px;float:left;text-decoration:none;display:inline-block}.page-header .logo:before{content:"";display:inline-block;vertical-align:middle;width:109px;height:35px;background-image:url("../images/logo.svg");background-size:109px 70px;background-repeat:no-repeat}.page-header .logo:after{display:inline-block;vertical-align:middle;margin-left:10px;content:attr(data-edition);font-weight:600;font-size:16px;color:#ef672f;margin-top:-2px}.page-header .logo span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.page-header .logo span.focusable:active,.page-header .logo span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.page-header .logo span.focusable:active,.page-header .logo span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.page-header .dropdown-menu{border:0}.admin-user{display:inline-block;vertical-align:top;position:relative;text-align:left}.admin-user-account{text-decoration:none;display:inline-block;padding:12px 14px;color:#f2ebde}.admin-user-account:after{font-family:"MUI-Icons";content:"\e02c";font-size:13px;line-height:13px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center;margin:-3px 0 0}.admin-user-account:link,.admin-user-account:visited{color:#f2ebde}.admin-user-account:focus,.admin-user-account:active,.admin-user-account:hover{color:#f2ebde;text-decoration:none}.active .admin-user-account{background-color:#fff;color:#676056}.admin-user-menu{padding:15px;white-space:nowrap;margin-top:0}.admin-user-menu li{border:0;padding:0}.admin-user-menu li:hover{background:0 0}.admin-user-menu a{display:block;color:#676056;font-size:13px;font-weight:400;line-height:1.385;padding:3px 12px 3px;text-decoration:none}.admin-user-menu a:focus,.admin-user-menu a:hover{text-decoration:underline}.admin-user-menu a:hover{color:#fff;background:#989287;text-decoration:none}.admin-user-menu a span:before{content:"("}.admin-user-menu a span:after{content:")"}.page-actions.fixed .page-actions-buttons{padding-right:15px}.page-main-actions{background:#e0dace;color:#645d53;padding:15px;margin-left:auto;margin-right:auto;box-sizing:border-box}.page-main-actions:before,.page-main-actions:after{content:"";display:table}.page-main-actions:after{clear:both}.page-main-actions:before,.page-main-actions:after{content:"";display:table}.page-main-actions:after{clear:both}.page-main-actions .page-actions{float:right}.page-main-actions .page-actions .page-actions-buttons{float:right;display:-webkit-flex;display:-ms-flexbox;display:flex;justify-content:flex-end}.page-main-actions .page-actions button,.page-main-actions .page-actions .action-add.mselect-button-add{margin-left:13px}.page-main-actions .page-actions button.primary,.page-main-actions .page-actions .action-add.mselect-button-add.primary{float:right;-ms-flex-order:2;-webkit-order:2;order:2}.page-main-actions .page-actions button.save:not(.primary),.page-main-actions .page-actions .action-add.mselect-button-add.save:not(.primary){float:right;-ms-flex-order:1;-webkit-order:1;order:1}.page-main-actions .page-actions button.back,.page-main-actions .page-actions button.action-back,.page-main-actions .page-actions button.delete,.page-main-actions .page-actions .action-add.mselect-button-add.back,.page-main-actions .page-actions .action-add.mselect-button-add.action-back,.page-main-actions .page-actions .action-add.mselect-button-add.delete{background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400;margin:0 13px}.page-main-actions .page-actions button.back:focus,.page-main-actions .page-actions button.action-back:focus,.page-main-actions .page-actions button.delete:focus,.page-main-actions .page-actions button.back:active,.page-main-actions .page-actions button.action-back:active,.page-main-actions .page-actions button.delete:active,.page-main-actions .page-actions .action-add.mselect-button-add.back:focus,.page-main-actions .page-actions .action-add.mselect-button-add.action-back:focus,.page-main-actions .page-actions .action-add.mselect-button-add.delete:focus,.page-main-actions .page-actions .action-add.mselect-button-add.back:active,.page-main-actions .page-actions .action-add.mselect-button-add.action-back:active,.page-main-actions .page-actions .action-add.mselect-button-add.delete:active{background:0 0;border:none}.page-main-actions .page-actions button.back:hover,.page-main-actions .page-actions button.action-back:hover,.page-main-actions .page-actions button.delete:hover,.page-main-actions .page-actions .action-add.mselect-button-add.back:hover,.page-main-actions .page-actions .action-add.mselect-button-add.action-back:hover,.page-main-actions .page-actions .action-add.mselect-button-add.delete:hover{background:0 0;border:none}.page-main-actions .page-actions button.back.disabled,.page-main-actions .page-actions button.action-back.disabled,.page-main-actions .page-actions button.delete.disabled,.page-main-actions .page-actions button.back[disabled],.page-main-actions .page-actions button.action-back[disabled],.page-main-actions .page-actions button.delete[disabled],fieldset[disabled] .page-main-actions .page-actions button.back,fieldset[disabled] .page-main-actions .page-actions button.action-back,fieldset[disabled] .page-main-actions .page-actions button.delete,.page-main-actions .page-actions .action-add.mselect-button-add.back.disabled,.page-main-actions .page-actions .action-add.mselect-button-add.action-back.disabled,.page-main-actions .page-actions .action-add.mselect-button-add.delete.disabled,.page-main-actions .page-actions .action-add.mselect-button-add.back[disabled],.page-main-actions .page-actions .action-add.mselect-button-add.action-back[disabled],.page-main-actions .page-actions .action-add.mselect-button-add.delete[disabled],fieldset[disabled] .page-main-actions .page-actions .action-add.mselect-button-add.back,fieldset[disabled] .page-main-actions .page-actions .action-add.mselect-button-add.action-back,fieldset[disabled] .page-main-actions .page-actions .action-add.mselect-button-add.delete{cursor:not-allowed;pointer-events:none;opacity:.5}.ie .page-main-actions .page-actions button.back,.ie .page-main-actions .page-actions button.action-back,.ie .page-main-actions .page-actions button.delete,.ie .page-main-actions .page-actions .action-add.mselect-button-add.back,.ie .page-main-actions .page-actions .action-add.mselect-button-add.action-back,.ie .page-main-actions .page-actions .action-add.mselect-button-add.delete{margin-top:6px}.page-main-actions .page-actions button.delete,.page-main-actions .page-actions .action-add.mselect-button-add.delete{color:#e22626;float:left;-ms-flex-order:-1;-webkit-order:-1;order:-1}.page-main-actions .page-actions button.back,.page-main-actions .page-actions button.action-back,.page-main-actions .page-actions .action-add.mselect-button-add.back,.page-main-actions .page-actions .action-add.mselect-button-add.action-back{float:left;-ms-flex-order:-1;-webkit-order:-1;order:-1;display:inline-block;text-decoration:none}.page-main-actions .page-actions button.back:before,.page-main-actions .page-actions button.action-back:before,.page-main-actions .page-actions .action-add.mselect-button-add.back:before,.page-main-actions .page-actions .action-add.mselect-button-add.action-back:before{font-family:'icons-blank-theme';content:'\e625';font-size:inherit;line-height:normal;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center;margin:0 2px 0 0}.page-main-actions .page-actions .actions-split{margin-left:13px;float:right;-ms-flex-order:2;-webkit-order:2;order:2}.page-main-actions .page-actions .actions-split button.primary,.page-main-actions .page-actions .actions-split .action-add.mselect-button-add.primary{float:left}.page-main-actions .page-actions .actions-split .dropdown-menu{text-align:left}.page-main-actions .page-actions .actions-split .dropdown-menu .item{display:block}.page-main-actions .page-actions.fixed{position:fixed;top:0;left:0;right:0;z-index:10;padding:0;background:-webkit-linear-gradient(top,#f5f2ed 0%,#f5f2ed 56%,rgba(245,242,237,0) 100%);background:-ms-linear-gradient(top,#f5f2ed 0%,#f5f2ed 56%,rgba(245,242,237,0) 100%);background:linear-gradient(to bottom,#f5f2ed 0%,#f5f2ed 56%,rgba(245,242,237,0) 100%);background:#e0dace}.page-main-actions .page-actions.fixed .page-actions-inner{position:relative;padding-top:15px;padding-bottom:15px;min-height:36px;text-align:right;box-sizing:border-box}.page-main-actions .page-actions.fixed .page-actions-inner:before,.page-main-actions .page-actions.fixed .page-actions-inner:after{content:"";display:table}.page-main-actions .page-actions.fixed .page-actions-inner:after{clear:both}.page-main-actions .page-actions.fixed .page-actions-inner:before,.page-main-actions .page-actions.fixed .page-actions-inner:after{content:"";display:table}.page-main-actions .page-actions.fixed .page-actions-inner:after{clear:both}.page-main-actions .page-actions.fixed .page-actions-inner:before{text-align:left;content:attr(data-title);float:left;font-size:20px;max-width:50%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lt-ie10 .page-main-actions .page-actions.fixed .page-actions-inner{background:#f5f2ed}.page-main-actions .store-switcher{margin-top:5px}.store-switcher{display:inline-block;font-size:13px}.store-switcher .label{margin-right:5px}.store-switcher .actions.dropdown{display:inline-block;position:relative}.store-switcher .actions.dropdown:before,.store-switcher .actions.dropdown:after{content:"";display:table}.store-switcher .actions.dropdown:after{clear:both}.store-switcher .actions.dropdown:before,.store-switcher .actions.dropdown:after{content:"";display:table}.store-switcher .actions.dropdown:after{clear:both}.store-switcher .actions.dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .actions.dropdown .action.toggle:after{font-family:'icons-blank-theme';content:'\e607';font-size:22px;line-height:20px;color:#645d53;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.store-switcher .actions.dropdown .action.toggle:hover:after{color:#645d53}.store-switcher .actions.dropdown .action.toggle:active:after{color:#645d53}.store-switcher .actions.dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .actions.dropdown .action.toggle.active:after{font-family:'icons-blank-theme';content:'\e618';font-size:22px;line-height:20px;color:#645d53;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.store-switcher .actions.dropdown .action.toggle.active:hover:after{color:#645d53}.store-switcher .actions.dropdown .action.toggle.active:active:after{color:#645d53}.store-switcher .actions.dropdown .dropdown-menu{margin:0;padding:0;list-style:none none;box-sizing:border-box;background:#fff;border:1px #ada89e solid;position:absolute;z-index:100;top:100%;min-width:195px;margin-top:4px;display:none;box-shadow:0 3px 3px rgba(0,0,0,.15)}.store-switcher .actions.dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .actions.dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .actions.dropdown.active{overflow:visible}.store-switcher .actions.dropdown.active .dropdown-menu{display:block}.store-switcher .actions.dropdown .action.toggle{background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400;color:#026294;line-height:normal;margin-top:2px;vertical-align:middle}.store-switcher .actions.dropdown .action.toggle:focus,.store-switcher .actions.dropdown .action.toggle:active{background:0 0;border:none}.store-switcher .actions.dropdown .action.toggle:hover{background:0 0;border:none}.store-switcher .actions.dropdown .action.toggle.disabled,.store-switcher .actions.dropdown .action.toggle[disabled],fieldset[disabled] .store-switcher .actions.dropdown .action.toggle{cursor:not-allowed;pointer-events:none;opacity:.5}.store-switcher .actions.dropdown ul.dropdown-menu{margin-top:4px;padding-top:5px;left:0}.store-switcher .actions.dropdown ul.dropdown-menu li{border:0;cursor:default}.store-switcher .actions.dropdown ul.dropdown-menu li:hover{cursor:default}.store-switcher .actions.dropdown ul.dropdown-menu li a,.store-switcher .actions.dropdown ul.dropdown-menu li span{padding:5px 13px;display:block;color:#645d53}.store-switcher .actions.dropdown ul.dropdown-menu li a{text-decoration:none}.store-switcher .actions.dropdown ul.dropdown-menu li a:hover{background:#edf9fb}.store-switcher .actions.dropdown ul.dropdown-menu li span{color:#ababab;cursor:default}.store-switcher .actions.dropdown ul.dropdown-menu li.current span{color:#645d53;background:#eee}.store-switcher .actions.dropdown ul.dropdown-menu .store-switcher-store a,.store-switcher .actions.dropdown ul.dropdown-menu .store-switcher-store span{padding-left:26px}.store-switcher .actions.dropdown ul.dropdown-menu .store-switcher-store-view a,.store-switcher .actions.dropdown ul.dropdown-menu .store-switcher-store-view span{padding-left:39px}.store-switcher .actions.dropdown ul.dropdown-menu .dropdown-toolbar{border-top:1px #ededed solid;margin-top:10px}.store-switcher .actions.dropdown ul.dropdown-menu .dropdown-toolbar a{display:inline-block;text-decoration:none;display:block}.store-switcher .actions.dropdown ul.dropdown-menu .dropdown-toolbar a:before{font-family:'icons-blank-theme';content:'\e606';font-size:20px;line-height:normal;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:text-top;text-align:center;margin:0 3px 0 -4px}.tooltip{display:inline-block;margin-left:5px}.tooltip .help span,.tooltip .help a{width:16px;height:16px;text-align:center;background:rgba(194,186,169,.5);cursor:pointer;border-radius:10px;vertical-align:middle;display:inline-block;text-decoration:none}.tooltip .help span:hover,.tooltip .help a:hover{background:#c2baa9}.tooltip .help span>span,.tooltip .help a>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tooltip .help span>span.focusable:active,.tooltip .help a>span.focusable:active,.tooltip .help span>span.focusable:focus,.tooltip .help a>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.tooltip .help span>span.focusable:active,.tooltip .help a>span.focusable:active,.tooltip .help span>span.focusable:focus,.tooltip .help a>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.tooltip .help span:before,.tooltip .help a:before{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;content:'?';font-size:13px;line-height:16px;color:#5a534a;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center}.tooltip .help span:before,.tooltip .help a:before{font-weight:700}.tooltip .tooltip-content{display:none;position:absolute;max-width:200px;margin-top:10px;margin-left:-19px;padding:4px 8px;border-radius:3px;background:#000;background:rgba(49,48,43,.8);color:#fff;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{content:'';position:absolute;width:0;height:0;top:-5px;left:20px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000;opacity:.8}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}button,.action-add.mselect-button-add{border-radius:2px;background-image:none;background:#f2ebde;padding:6px 13px;color:#645d53;border:1px solid #ada89e;cursor:pointer;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;line-height:1.4rem;box-sizing:border-box;margin:0;vertical-align:middle}button:focus,button:active,.action-add.mselect-button-add:focus,.action-add.mselect-button-add:active{background:#cac3b4;border:1px solid #989287}button:hover,.action-add.mselect-button-add:hover{background:#cac3b4}button.disabled,button[disabled],fieldset[disabled] button,.action-add.mselect-button-add.disabled,.action-add.mselect-button-add[disabled],fieldset[disabled] .action-add.mselect-button-add{cursor:default;pointer-events:none;opacity:.5}button.primary,.action-add.mselect-button-add.primary{background-image:none;background:#007dbd;padding:6px 13px;color:#fff;border:1px solid #0a6c9f;cursor:pointer;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;box-sizing:border-box;vertical-align:middle}button.primary:focus,button.primary:active,.action-add.mselect-button-add.primary:focus,.action-add.mselect-button-add.primary:active{background:#026294;border:1px solid #004c74;color:#fff}button.primary:hover,.action-add.mselect-button-add.primary:hover{background:#026294;border:1px solid #026294}button.primary.disabled,button.primary[disabled],fieldset[disabled] button.primary,.action-add.mselect-button-add.primary.disabled,.action-add.mselect-button-add.primary[disabled],fieldset[disabled] .action-add.mselect-button-add.primary{cursor:default;pointer-events:none;opacity:.5}.actions-split{display:inline-block;position:relative;vertical-align:middle}.actions-split button,.actions-split .action-add.mselect-button-add{margin-left:0!important}.actions-split:before,.actions-split:after{content:"";display:table}.actions-split:after{clear:both}.actions-split:before,.actions-split:after{content:"";display:table}.actions-split:after{clear:both}.actions-split .action-default{float:left;margin:0}.actions-split .action-toggle{float:right;margin:0}.actions-split button.action-default,.actions-split .action-add.mselect-button-add.action-default{border-top-right-radius:0;border-bottom-right-radius:0}.actions-split button+.action-toggle,.actions-split .action-add.mselect-button-add+.action-toggle{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.actions-split .action-toggle{padding:6px 5px;display:inline-block;text-decoration:none}.actions-split .action-toggle>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.actions-split .action-toggle>span.focusable:active,.actions-split .action-toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.actions-split .action-toggle>span.focusable:active,.actions-split .action-toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.actions-split .action-toggle:after{font-family:'icons-blank-theme';content:'\e607';font-size:22px;line-height:14px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.actions-split .action-toggle:hover:after{color:inherit}.actions-split .action-toggle:active:after{color:inherit}.actions-split .action-toggle.active{display:inline-block;text-decoration:none}.actions-split .action-toggle.active>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.actions-split .action-toggle.active>span.focusable:active,.actions-split .action-toggle.active>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.actions-split .action-toggle.active>span.focusable:active,.actions-split .action-toggle.active>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.actions-split .action-toggle.active:after{font-family:'icons-blank-theme';content:'\e618';font-size:22px;line-height:14px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.actions-split .action-toggle.active:hover:after{color:inherit}.actions-split .action-toggle.active:active:after{color:inherit}.actions-split .dropdown-menu{margin:0;padding:0;list-style:none none;box-sizing:border-box;background:#fff;border:1px solid #bbb;position:absolute;z-index:100;top:100%;min-width:175px;margin-top:4px;display:none;box-shadow:0 3px 3px rgba(0,0,0,.15)}.actions-split .dropdown-menu li{margin:0;padding:3px 5px}.actions-split .dropdown-menu li:hover{background:#e8e8e8;cursor:pointer}.actions-split .dropdown-menu:before,.actions-split .dropdown-menu:after{content:"";position:absolute;display:block;width:0;height:0;border-bottom-style:solid}.actions-split .dropdown-menu:before{z-index:99;border:solid 6px;border-color:transparent transparent #fff}.actions-split .dropdown-menu:after{z-index:98;border:solid 7px;border-color:transparent transparent #bbb}.actions-split .dropdown-menu:before{top:-12px;right:10px}.actions-split .dropdown-menu:after{top:-14px;right:9px}.actions-split.active{overflow:visible}.actions-split.active .dropdown-menu{display:block}.actions-split .action-toggle:after{height:13px}.page-content:after{content:"";display:table;clear:both}.page-wrapper>.page-content{margin-bottom:20px}.page-footer{padding:15px 0}.page-footer-wrapper{background-color:#e0dacf;margin-top:auto}.page-footer:after{content:"";display:table;clear:both}.footer-legal{float:right;width:550px}.footer-legal .link-report,.footer-legal .magento-version,.footer-legal .copyright{font-size:13px}.footer-legal:before{content:"";display:inline-block;vertical-align:middle;position:absolute;z-index:1;margin-top:2px;margin-left:-35px;width:30px;height:35px;background-size:109px 70px;background:url("../images/logo.svg") no-repeat 0 -21px}.icon-error{margin-left:15px;color:#c00815;font-size:11px}.icon-error:before{font-family:'MUI-Icons';content:"\e086";font-size:13px;line-height:13px;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center;margin:-1px 5px 0 0}.ui-widget-overlay{position:fixed}.control .nested{padding:0}.control *:first-child{margin-bottom:0}.field-tooltip{display:inline-block;vertical-align:top;margin-top:5px;position:relative;z-index:1;width:0;overflow:visible}.field-choice .field-tooltip{margin-top:10px}.field-tooltip:hover{z-index:99}.field-tooltip-action{position:relative;z-index:2;margin-left:18px;width:22px;height:22px;display:inline-block;cursor:pointer}.field-tooltip-action:before{content:"?";font-weight:500;font-size:18px;display:inline-block;overflow:hidden;height:22px;border-radius:11px;line-height:22px;width:22px;text-align:center;color:#fff;background-color:#514943}.field-tooltip-action span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.field-tooltip-action span.focusable:active,.field-tooltip-action span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.field-tooltip-action span.focusable:active,.field-tooltip-action span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.control-text:focus+.field-tooltip-content,.field-tooltip:hover .field-tooltip-content{display:block}.field-tooltip-content{display:none;position:absolute;z-index:1;width:320px;background:#fff8d7;padding:15px 25px;right:-66px;border:1px solid #adadad;border-radius:1px;bottom:42px;box-shadow:0 2px 8px 0 rgba(0,0,0,.3)}.field-tooltip-content:after,.field-tooltip-content:before{content:"";display:block;width:0;height:0;border:16px solid transparent;border-top-color:#adadad;position:absolute;right:20px;top:100%;z-index:3}.field-tooltip-content:after{border-top-color:#fff8d7;margin-top:-1px;z-index:4}.form__field.field-error .control [class*=control-]{border-color:#e22626}.form__field.field-error .control [class*=control-]:before{border-color:#e22626}.form__field .mage-error{border:1px solid #e22626;display:block;margin:2px 0 0;padding:6px 10px 10px;background:#fff8d6;color:#555;font-size:12px;font-weight:500;box-sizing:border-box;max-width:380px}.no-flexbox.no-flexboxlegacy .form__field .control-addon+.mage-error{display:inline-block;width:100%}.form__field{position:relative;z-index:1}.form__field:hover{z-index:2}.control .form__field{position:static}.form__field[data-config-scope]:before{content:attr(data-config-scope);display:inline-block;position:absolute;color:gray;right:0;top:6px}.control .form__field[data-config-scope]:nth-child(n+2):before{content:""}.form__field.field-disabled>.label{color:#999}.form__field.field-disabled.field .control [class*=control-][disabled]{background-color:#e9e9e9;opacity:.5;color:#303030;border-color:#adadad}.control-fields .label~.control{width:100%}.form__field{border:0;padding:0}.form__field .note{color:#303030;padding:0;margin:10px 0 0;max-width:380px}.form__field .note:before{display:none}.form__field.form__field{margin-bottom:0}.form__field.form__field+.form__field.form__field{margin-top:15px}.form__field.form__field:not(.choice)~.choice{margin-left:20px;margin-top:5px}.form__field.form__field.choice~.choice{margin-top:9px}.form__field.form__field~.choice:last-child{margin-bottom:8px}.fieldset>.form__field{margin-bottom:30px}.form__field .label{color:#303030}.form__field:not(.choice)>.label{font-size:14px;font-weight:600;width:30%;padding-right:30px;padding-top:0;line-height:33px;white-space:nowrap}.form__field:not(.choice)>.label:before{content:".";visibility:hidden;width:0;margin-left:-7px;overflow:hidden}.form__field:not(.choice)>.label span{white-space:normal;display:inline-block;vertical-align:middle;line-height:1.2}.form__field.required>.label:after{content:"";margin-left:0}.form__field.required>.label span:after{content:"*";color:#eb5202;display:inline;font-weight:500;font-size:16px;margin-top:2px;position:absolute;z-index:1;margin-left:10px}.form__field .control-file{margin-top:6px}.form__field .control-select{line-height:33px}.form__field .control-select:not([multiple]),.form__field .control-text{height:33px;max-width:380px}.form__field .control-addon{max-width:380px}.form__field .control-textarea,.form__field .control-select,.form__field .control-text{border:1px solid #adadad;border-radius:1px;padding:0 10px;color:#303030;background-color:#fff;font-weight:500;font-size:15px;min-width:11em}.form__field .control-textarea:focus,.form__field .control-select:focus,.form__field .control-text:focus{outline:0;border-color:#007bdb;box-shadow:none}.form__field .control-text{line-height:auto}.form__field .control-textarea{padding-top:6px;padding-bottom:6px;line-height:1.18em}.form__field .control-select[multiple],.form__field .control-textarea{width:100%;height:calc(6*1.2em + 14px)}.form__field .control-value{display:inline-block;padding:6px 10px}.form__field .control-fields .form__field:nth-child(n+2):not(.choice)>.label{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.form__field .control-fields .form__field:nth-child(n+2):not(.choice)>.label.focusable:active,.form__field .control-fields .form__field:nth-child(n+2):not(.choice)>.label.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.form__field .control-fields .form__field:nth-child(n+2):not(.choice)>.label.focusable:active,.form__field .control-fields .form__field:nth-child(n+2):not(.choice)>.label.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.form__field .control-select{padding:0}.form__field .control-select option{box-sizing:border-box;padding:4px 10px;display:block}.form__field .control-select optgroup{font-weight:600;display:block;padding:4px 10px;line-height:33px;list-style:inside;font-style:normal}.form__field .control-range>.form__field:nth-child(2):before{content:"\2014";content:":";display:inline-block;margin-left:-25px;float:left;width:20px;line-height:33px;text-align:center}.form__field.choice{position:relative;z-index:1;padding-top:8px;padding-left:26px;padding-right:0}.form__field.choice .label{font-weight:500;padding:0;display:inline;float:none;line-height:18px}.form__field.choice input{position:absolute;top:8px;margin-top:3px!important}.form__field.choice input[disabled]+.label{opacity:.5;cursor:not-allowed}.control>.form__field.choice{max-width:380px}.control>.form__field.choice:nth-child(1):nth-last-child(2),.control>.form__field.choice:nth-child(2):nth-last-child(1){display:inline-block}.control>.form__field.choice:nth-child(1):nth-last-child(2)+.choice,.control>.form__field.choice:nth-child(2):nth-last-child(1)+.choice{margin-left:41px;margin-top:0}.control>.form__field.choice:nth-child(1):nth-last-child(2)+.choice:before,.control>.form__field.choice:nth-child(2):nth-last-child(1)+.choice:before{content:"";position:absolute;display:inline-block;height:20px;top:8px;left:-20px;width:1px;background:#ccc}.form__field.choice .label{cursor:pointer}.form__field.choice .label:before{content:"";position:absolute;z-index:1;border:1px solid #adadad;width:14px;height:14px;top:10px;left:0;border-radius:2px;background:url("../Magento_Ui/images/choice_bkg.png") no-repeat -100% -100%}.form__field.choice input:focus+.label:before{outline:0;border-color:#007bdb}.form__field.choice .control-radio+.label:before{border-radius:8px}.form__field.choice .control-radio:checked+.label:before{background-position:-26px -1px}.form__field.choice .control-checkbox:checked+.label:before{background-position:-1px -1px}.form__field.choice input{opacity:0}.fieldset>.form__field.choice{margin-left:30%}.form__field .control-after,.form__field .control-before{border:0;color:#858585;font-weight:300;font-size:15px;line-height:33px;display:inline-block;height:33px;box-sizing:border-box;padding:0 3px}.no-flexbox.no-flexboxlegacy .form__field .control-before,.no-flexbox.no-flexboxlegacy .form__field .control-addon{float:left;white-space:nowrap}.form__field .control-addon{display:inline-flex;max-width:380px;width:100%;flex-flow:row nowrap;position:relative;z-index:1}.form__field .control-addon>*{position:relative;z-index:1}.form__field .control-addon .control-text[disabled][type],.form__field .control-addon .control-select[disabled][type],.form__field .control-addon .control-select,.form__field .control-addon .control-text{background:transparent!important;border:0;width:auto;vertical-align:top;order:1;flex:1}.form__field .control-addon .control-text[disabled][type]:focus,.form__field .control-addon .control-select[disabled][type]:focus,.form__field .control-addon .control-select:focus,.form__field .control-addon .control-text:focus{box-shadow:none}.form__field .control-addon .control-text[disabled][type]:focus+label:before,.form__field .control-addon .control-select[disabled][type]:focus+label:before,.form__field .control-addon .control-select:focus+label:before,.form__field .control-addon .control-text:focus+label:before{outline:0;border-color:#007bdb}.form__field .control-addon .control-text[disabled][type]+label,.form__field .control-addon .control-select[disabled][type]+label,.form__field .control-addon .control-select+label,.form__field .control-addon .control-text+label{padding-left:10px;position:static!important;z-index:0}.form__field .control-addon .control-text[disabled][type]+label>*,.form__field .control-addon .control-select[disabled][type]+label>*,.form__field .control-addon .control-select+label>*,.form__field .control-addon .control-text+label>*{vertical-align:top;position:relative;z-index:2}.form__field .control-addon .control-text[disabled][type]+label:before,.form__field .control-addon .control-select[disabled][type]+label:before,.form__field .control-addon .control-select+label:before,.form__field .control-addon .control-text+label:before{box-sizing:border-box;border-radius:1px;border:1px solid #adadad;content:"";display:block;position:absolute;top:0;left:0;width:100%;height:100%;z-index:0;background:#fff}.form__field .control-addon .control-text[disabled][type][disabled]+label:before,.form__field .control-addon .control-select[disabled][type][disabled]+label:before,.form__field .control-addon .control-select[disabled]+label:before,.form__field .control-addon .control-text[disabled]+label:before{opacity:.5;background:#e9e9e9}.form__field .control-after{order:3}.form__field .control-after:last-child{padding-right:10px}.form__field .control-before{order:0}.form__field .control-some{display:flex}.form__field [class*=control-grouped]{display:table;width:100%;table-layout:fixed;box-sizing:border-box}.form__field [class*=control-grouped]>.form__field{display:table-cell;width:50%;vertical-align:top}.form__field [class*=control-grouped]>.form__field>.control{width:100%;float:none}.form__field [class*=control-grouped]>.form__field:nth-child(n+2){padding-left:20px}.form__field [class*=control-grouped]>.form__field:nth-child(n+2):not(.choice) .label{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.form__field [class*=control-grouped]>.form__field:nth-child(n+2):not(.choice) .label.focusable:active,.form__field [class*=control-grouped]>.form__field:nth-child(n+2):not(.choice) .label.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.form__field [class*=control-grouped]>.form__field:nth-child(n+2):not(.choice) .label.focusable:active,.form__field [class*=control-grouped]>.form__field:nth-child(n+2):not(.choice) .label.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.form__field [required]{box-shadow:none}fieldset.form__field{position:relative}fieldset.form__field [class*=control-grouped]>.form__field:first-child>.label,fieldset.form__field .control-fields>.form__field:first-child>.label{position:absolute;left:0;top:0;opacity:0;cursor:pointer;width:30%}.control-text+.ui-datepicker-trigger{background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;line-height:inherit;font-weight:400;text-decoration:none;margin-left:-40px;display:inline-block}.control-text+.ui-datepicker-trigger img{display:none}.control-text+.ui-datepicker-trigger:focus,.control-text+.ui-datepicker-trigger:active{background:0 0;border:none}.control-text+.ui-datepicker-trigger:hover{background:0 0;border:none}.control-text+.ui-datepicker-trigger.disabled,.control-text+.ui-datepicker-trigger[disabled],fieldset[disabled] .control-text+.ui-datepicker-trigger{cursor:not-allowed;pointer-events:none;opacity:.5}.control-text+.ui-datepicker-trigger>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.control-text+.ui-datepicker-trigger>span.focusable:active,.control-text+.ui-datepicker-trigger>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.control-text+.ui-datepicker-trigger>span.focusable:active,.control-text+.ui-datepicker-trigger>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.control-text+.ui-datepicker-trigger:after{font-family:'icons-blank-theme';content:'\e612';font-size:38px;line-height:33px;color:#514943;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}[class*=tab-nav-item]:not(ul):active,[class*=tab-nav-item]:not(ul):focus{box-shadow:none;outline:none}.customer-index-edit .col-2-left-layout,.customer-index-edit .col-1-layout{background:#fff}.customer-index-edit{background:#fff}.customer-index-edit .col-2-left-layout{background:#fff}.customer-index-edit .main-col{padding-left:40px}.customer-index-edit .page-main-actions{background:0 0}.tab-nav.block{margin-bottom:40px}.tab-nav.block:first-child{margin-top:16px}.tab-nav.block .block-title{padding:7px 20px}.tab-nav-items{padding:0;border:1px solid #d3d3d3;box-shadow:0 0 4px rgba(50,50,50,.35);margin:0 0 40px;background:#f7f7f7}.tab-nav-item{padding:0;list-style-type:none;border-bottom:1px solid #e0e0e0;position:relative;margin:0 15px;z-index:1}.tab-nav-item:last-child{border-bottom:0}.tab-nav-item.ui-state-active{z-index:2;background:#fff;padding:1px 14px;border:2px solid #eb5202;margin:-1px}.tab-nav-item.ui-state-active .tab-nav-item-link{padding:13px 15px 13px;color:#eb5202}.tab-nav-item.ui-tabs-loading{position:relative;z-index:1}.tab-nav-item.ui-tabs-loading:before{content:"";display:block;position:absolute;z-index:2;background:url("../images/loader-2.gif") no-repeat 50% 50%;background-size:120px;width:20px;height:20px;top:13px;left:-10px}.tab-nav-item.ui-tabs-loading.ui-state-active:before{top:12px;left:4px}.tab-nav-item-link{display:block;padding:15px;color:#666;line-height:1}.tab-nav-item-link:focus,.tab-nav-item-link:active,.tab-nav-item-link:hover{outline:0;color:#eb5202;text-decoration:none}.ui-state-active .tab-nav-item-link{color:#666;font-weight:600}.tab-nav-item-link.changed{font-style:italic}.listing-tiles{overflow:hidden;margin-top:-10px;margin-left:-10px}.listing-tiles .listing-tile{background-color:#f2ebde;display:block;width:238px;height:200px;float:left;border:1px solid #676056;margin-top:10px;margin-left:10px;border-radius:4px;text-align:center}.listing-tiles .listing-tile.disabled{border-color:red}.listing-tiles .listing-tile.enabled{border-color:green}.listing .disabled{color:red}.listing .enabled{color:green}.pager{text-align:left;padding-bottom:10px}.pager:before,.pager:after{content:"";display:table}.pager:after{clear:both}.pager:before,.pager:after{content:"";display:table}.pager:after{clear:both}.pager [data-part=left]{display:inline-block;width:45%;float:left;text-align:left}.pager [data-part=right]{display:inline-block;width:45%;text-align:right;float:right;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.pager .action-next{cursor:pointer}.pager .action-previous{cursor:pointer}.pager{text-align:left}.pager [data-part=left]{display:inline-block;width:45%;text-align:left}.pager [data-part=right]{display:inline-block;width:45%;text-align:right;float:right}.grid .col-title{min-width:90px;text-align:center}.grid-actions [data-part=search]{display:inline-block;margin:0 30px}.grid-actions [data-part=search] input[type=text]{vertical-align:bottom;width:460px}.grid .actions-split .dropdown-menu{right:auto;left:auto;text-align:left;color:#676056;font-weight:400}.grid .actions-split .dropdown-menu:after{right:auto;left:9px}.grid .actions-split .dropdown-menu:before{right:auto;left:10px}.grid .grid-actions{padding:10px 0}.grid .hor-scroll{padding-top:10px}.grid .select-box{display:inline-block;vertical-align:top;margin:-12px -10px -7px;padding:12px 10px 7px;width:100%}.filters-toggle{background:#f2ebde;padding:6px 13px;color:#645d53;border:1px solid #ada89e;cursor:pointer;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;line-height:1.4rem;box-sizing:border-box;margin:3px;vertical-align:middle;display:inline-block;background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400}.filters-toggle:after{font-family:'icons-blank-theme';content:'\e607';font-size:30px;line-height:15px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.filters-toggle:hover:after{color:inherit}.filters-toggle:active:after{color:inherit}.filters-toggle:focus,.filters-toggle:active{background:#cac3b4;border:1px solid #989287}.filters-toggle:hover{background:#cac3b4}.filters-toggle.disabled,.filters-toggle[disabled],fieldset[disabled] .filters-toggle{cursor:default;pointer-events:none;opacity:.5}.filters-toggle:focus,.filters-toggle:active{background:0 0;border:none}.filters-toggle:hover{background:0 0;border:none}.filters-toggle.disabled,.filters-toggle[disabled],fieldset[disabled] .filters-toggle{cursor:not-allowed;pointer-events:none;opacity:.5}.filters-toggle:after{margin-top:2px;margin-left:-3px}.filters-toggle.active:after{content:'\e618'}.filters-current{padding:10px 0;display:none}.filters-current.active{display:block}.filters-items{margin:0;padding:0;list-style:none none;display:inline}.filters-item{display:inline-block;margin:0 5px 5px 0;padding:2px 2px 2px 4px;border-radius:3px;background:#f7f3eb}.filters-item .item-label{font-weight:600}.filters-item .item-label:after{content:": "}.filters-item .action-remove{background-image:none;background:#f2ebde;padding:6px 13px;color:#645d53;border:1px solid #ada89e;cursor:pointer;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;line-height:1.4rem;box-sizing:border-box;margin:3px;vertical-align:middle;display:inline-block;text-decoration:none;padding:0}.filters-item .action-remove>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.filters-item .action-remove>span.focusable:active,.filters-item .action-remove>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters-item .action-remove>span.focusable:active,.filters-item .action-remove>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters-item .action-remove:before{font-family:'icons-blank-theme';content:'\e616';font-size:16px;line-height:16px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.filters-item .action-remove:hover:before{color:inherit}.filters-item .action-remove:active:before{color:inherit}.filters-item .action-remove:focus,.filters-item .action-remove:active{background:#cac3b4;border:1px solid #989287}.filters-item .action-remove:hover{background:#cac3b4}.filters-item .action-remove.disabled,.filters-item .action-remove[disabled],fieldset[disabled] .filters-item .action-remove{cursor:default;pointer-events:none;opacity:.5}.filters-form{position:relative;z-index:1;margin:14px 0;background:#fff;border:1px solid #bbb;box-shadow:0 3px 3px rgba(0,0,0,.15)}.filters-form .action-close{position:absolute;top:3px;right:7px;background:#f2ebde;padding:6px 13px;color:#645d53;border:1px solid #ada89e;cursor:pointer;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;line-height:1.4rem;box-sizing:border-box;margin:3px;vertical-align:middle;display:inline-block;background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400}.filters-form .action-close>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.filters-form .action-close>span.focusable:active,.filters-form .action-close>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters-form .action-close>span.focusable:active,.filters-form .action-close>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters-form .action-close:before{font-family:'icons-blank-theme';content:'\e616';font-size:42px;line-height:42px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.filters-form .action-close:hover:before{color:inherit}.filters-form .action-close:active:before{color:inherit}.filters-form .action-close:focus,.filters-form .action-close:active{background:#cac3b4;border:1px solid #989287}.filters-form .action-close:hover{background:#cac3b4}.filters-form .action-close.disabled,.filters-form .action-close[disabled],fieldset[disabled] .filters-form .action-close{cursor:default;pointer-events:none;opacity:.5}.filters-form .action-close:focus,.filters-form .action-close:active{background:0 0;border:none}.filters-form .action-close:hover{background:0 0;border:none}.filters-form .action-close.disabled,.filters-form .action-close[disabled],fieldset[disabled] .filters-form .action-close{cursor:not-allowed;pointer-events:none;opacity:.5}.filters-actions{margin:18px;text-align:right}.filters-fieldset{padding-bottom:0}.filters-fieldset .field{border:0;margin:0 0 20px;box-sizing:border-box;display:inline-block;padding:0 12px 0 0;width:33.33333333%;vertical-align:top}.filters-fieldset .field:before,.filters-fieldset .field:after{content:"";display:table}.filters-fieldset .field:after{clear:both}.filters-fieldset .field:before,.filters-fieldset .field:after{content:"";display:table}.filters-fieldset .field:after{clear:both}.filters-fieldset .field.choice:before,.filters-fieldset .field.no-label:before{box-sizing:border-box;content:" ";height:1px;float:left;padding:6px 15px 0 0;width:35%}.filters-fieldset .field .description{box-sizing:border-box;float:left;padding:6px 15px 0 0;text-align:right;width:35%}.filters-fieldset .field:not(.choice)>.label{box-sizing:border-box;float:left;padding:6px 15px 0 0;text-align:right;width:35%}.filters-fieldset .field:not(.choice)>.control{float:left;width:65%}.filters-fieldset .field:last-child{margin-bottom:0}.filters-fieldset .field+.fieldset{clear:both}.filters-fieldset .field>.label{font-weight:700}.filters-fieldset .field>.label+br{display:none}.filters-fieldset .field .choice input{vertical-align:top}.filters-fieldset .field .fields.group:before,.filters-fieldset .field .fields.group:after{content:"";display:table}.filters-fieldset .field .fields.group:after{clear:both}.filters-fieldset .field .fields.group:before,.filters-fieldset .field .fields.group:after{content:"";display:table}.filters-fieldset .field .fields.group:after{clear:both}.filters-fieldset .field .fields.group .field{box-sizing:border-box;float:left}.filters-fieldset .field .fields.group.group-2 .field{width:50% !important}.filters-fieldset .field .fields.group.group-3 .field{width:33.3% !important}.filters-fieldset .field .fields.group.group-4 .field{width:25% !important}.filters-fieldset .field .fields.group.group-5 .field{width:20% !important}.filters-fieldset .field .addon{display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;padding:0;width:100%}.filters-fieldset .field .addon textarea,.filters-fieldset .field .addon select,.filters-fieldset .field .addon input{-ms-flex-order:2;-webkit-order:2;order:2;-webkit-flex-basis:100%;flex-basis:100%;box-shadow:none;display:inline-block;margin:0;width:auto}.filters-fieldset .field .addon .addbefore,.filters-fieldset .field .addon .addafter{-ms-flex-order:3;-webkit-order:3;order:3;display:inline-block;box-sizing:border-box;background:#fff;border:1px solid #c2c2c2;border-radius:1px;height:32px;width:100%;padding:0 9px;font-size:14px;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;line-height:1.428571429;background-clip:padding-box;vertical-align:baseline;width:auto;white-space:nowrap;vertical-align:middle}.filters-fieldset .field .addon .addbefore:disabled,.filters-fieldset .field .addon .addafter:disabled{opacity:.5}.filters-fieldset .field .addon .addbefore::-moz-placeholder,.filters-fieldset .field .addon .addafter::-moz-placeholder{color:#c2c2c2}.filters-fieldset .field .addon .addbefore::-webkit-input-placeholder,.filters-fieldset .field .addon .addafter::-webkit-input-placeholder{color:#c2c2c2}.filters-fieldset .field .addon .addbefore:-ms-input-placeholder,.filters-fieldset .field .addon .addafter:-ms-input-placeholder{color:#c2c2c2}.filters-fieldset .field .addon .addbefore{float:left;-ms-flex-order:1;-webkit-order:1;order:1}.filters-fieldset .field .additional{margin-top:10px}.filters-fieldset .field.required>.label:after{content:'*';font-size:1.2rem;color:#e02b27;margin:0 0 0 5px}.filters-fieldset .field .note{font-size:1.2rem;margin:3px 0 0;padding:0;display:inline-block;text-decoration:none}.filters-fieldset .field .note:before{font-family:'icons-blank-theme';content:'\e618';font-size:24px;line-height:12px;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.filters-fieldset .field .label{color:#676056;font-size:13px;font-weight:600;margin:0}.filters .field-date .group .hasDatepicker{width:100%;padding-right:30px}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger{background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;line-height:inherit;font-weight:400;text-decoration:none;margin-left:-33px;display:inline-block;width:30px}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger img{display:none}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger:focus,.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger:active{background:0 0;border:none}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger:hover{background:0 0;border:none}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger.disabled,.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger[disabled],fieldset[disabled] .filters .field-date .group .hasDatepicker+.ui-datepicker-trigger{cursor:not-allowed;pointer-events:none;opacity:.5}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger>span.focusable:active,.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger>span.focusable:active,.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.filters .field-date .group .hasDatepicker+.ui-datepicker-trigger:after{font-family:'icons-blank-theme';content:'\e612';font-size:35px;line-height:30px;color:#514943;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:middle;text-align:center}.filters .field-range .group .field{margin-bottom:0}.filters .field-range .group .control{width:100%;box-sizing:border-box;padding-right:0;position:relative;z-index:1}.mass-select{position:relative;margin:-6px -10px;padding:6px 2px 6px 10px;z-index:1;white-space:nowrap}.mass-select.active{background:rgba(0,0,0,.2)}.mass-select-toggle{background:#f2ebde;padding:6px 13px;color:#645d53;border:1px solid #ada89e;cursor:pointer;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.3rem;font-weight:500;line-height:1.4rem;box-sizing:border-box;margin:3px;vertical-align:middle;display:inline-block;background-image:none;background:0 0;border:0;margin:0;padding:0;-moz-box-sizing:content-box;box-shadow:none;text-shadow:none;text-decoration:none;line-height:inherit;font-weight:400}.mass-select-toggle>span{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.mass-select-toggle>span.focusable:active,.mass-select-toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.mass-select-toggle>span.focusable:active,.mass-select-toggle>span.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.mass-select-toggle:before{font-family:'icons-blank-theme';content:'\e607';font-size:30px;line-height:15px;color:inherit;overflow:hidden;speak:none;font-weight:400;-webkit-font-smoothing:antialiased;display:inline-block;vertical-align:top;text-align:center;margin:0}.mass-select-toggle:hover:before{color:inherit}.mass-select-toggle:active:before{color:inherit}.mass-select-toggle:focus,.mass-select-toggle:active{background:#cac3b4;border:1px solid #989287}.mass-select-toggle:hover{background:#cac3b4}.mass-select-toggle.disabled,.mass-select-toggle[disabled],fieldset[disabled] .mass-select-toggle{cursor:default;pointer-events:none;opacity:.5}.mass-select-toggle:focus,.mass-select-toggle:active{background:0 0;border:none}.mass-select-toggle:hover{background:0 0;border:none}.mass-select-toggle.disabled,.mass-select-toggle[disabled],fieldset[disabled] .mass-select-toggle{cursor:not-allowed;pointer-events:none;opacity:.5}.mass-select-toggle:before{margin-top:-2px;text-indent:-5px;color:#fff}.mass-select-toggle:hover:before{color:#fff}.mass-select-toggle:active:before,.mass-select-toggle.active:before{content:'\e618'}.mass-select-field{display:inline}.mass-select-menu{display:none;position:absolute;top:100%;left:0;text-align:left;margin:0;padding:0;list-style:none none;background:#fff;border:1px solid #bbb;min-width:175px;box-shadow:0 3px 3px rgba(0,0,0,.15)}.mass-select-menu li{margin:0;padding:4px 15px;border-bottom:1px solid #e5e5e5}.mass-select-menu li:hover{background:#e8e8e8;cursor:pointer}.mass-select-menu span{font-weight:400;font-size:13px;color:#645d53}.mass-select-menu.active{display:block}.grid-loading-mask{position:absolute;left:0;top:0;right:0;bottom:0;background:rgba(255,255,255,.5);z-index:100}.grid-loading-mask .grid-loader{position:absolute;margin:auto;left:0;top:0;right:0;bottom:0;width:218px;height:149px;background:url('../images/loader-2.gif') 50% 50% no-repeat}.addon input{border-width:1px 0 1px 1px}.addon input~.addafter strong{display:inline-block;background:#fff;line-height:24px;margin:0 3px 0 -2px;padding-left:4px;padding-right:4px;position:relative;font-size:12px;top:0}.addon input:focus~.addafter{border-color:#75b9f0;box-shadow:0 0 8px rgba(82,168,236,.6)}.addon input:focus~.addafter strong{margin-top:0}.addon .addafter{background:0 0;color:#a6a6a6;border-width:1px 1px 1px 0;border-radius:2px 2px 0 0;padding:0;border-color:#ada89e}.addon .pager input{border-width:1px}.field .control input[type=text][disabled],.field .control input[type=text][disabled]~.addafter,.field .control select[disabled],.field .control select[disabled]~.addafter{background-color:#fff;border-color:#eee;box-shadow:none;color:#999}.field .control input[type=text][disabled]~.addafter strong,.field .control select[disabled]~.addafter strong{background-color:#fff}.field-price.addon{direction:rtl}.field-price.addon>*{direction:ltr}.field-price.addon .addafter{border-width:1px 0 1px 1px;border-radius:2px 0 0 2px}.field-price.addon input:first-child{border-radius:0 2px 2px 0}.field-price input{border-width:1px 1px 1px 0}.field-price input:focus{box-shadow:0 0 8px rgba(82,168,236,.6)}.field-price input:focus~label.addafter{box-shadow:0 0 8px rgba(82,168,236,.6)}.field-price input~label.addafter strong{margin-left:2px;margin-right:-2px}.field-price.addon>input{width:99px;float:left}.field-price .control{position:relative}.field-price label.mage-error{position:absolute;left:0;top:30px}.version-fieldset .grid-actions{border-bottom:1px solid #f2ebde;margin:0 0 15px;padding:0 0 15px}.navigation>ul,.message-system,.page-header,.page-actions.fixed .page-actions-inner,.page-content,.page-footer{width:auto;min-width:960px;max-width:1300px;margin:0 auto;padding-left:15px;padding-right:15px;box-sizing:border-box;width:100%}.pager label.page,.filters .field-range .group .label,.mass-select-field .label{clip:rect(0,0,0,0);border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visually-hidden.focusable:active,.visually-hidden.focusable:focus,.pager label.page.focusable:active,.pager label.page.focusable:focus,.filters .field-range .group .label.focusable:active,.filters .field-range .group .label.focusable:focus,.mass-select-field .label.focusable:active,.mass-select-field .label.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}table th.required:after,.data-table th.required-entry:after,.data-table td.required-entry:after,.grid-actions .filter.required .label span:after,.grid-actions .required:after,.accordion .config .data-table td.required-entry:after{content:'*';color:#e22626;font-weight:400;margin-left:3px}.grid th.required:after,.grid th .required:after{content:'*';color:#f9d4d4;font-weight:400;margin-left:3px}.grid td.col-period,.grid td.col-date,.grid td.col-date_to,.grid td.col-date_from,.grid td.col-ended_at,.grid td.col-created_at,.grid td.col-updated_at,.grid td.col-customer_since,.grid td.col-session_start_time,.grid td.col-last_activity,.grid td.col-email,.grid td.col-name,.grid td.col-sku,.grid td.col-firstname,.grid td.col-lastname,.grid td.col-title,.grid td.col-label,.grid td.col-product,.grid td.col-set_name,.grid td.col-websites,.grid td.col-time,.grid td.col-billing_name,.grid td.col-shipping_name,.grid td.col-phone,.grid td.col-type,.product-options .grouped-items-table .col-name,.product-options .grouped-items-table .col-sku,.sales-order-create-index .data-table .col-product,[class^=' adminhtml-rma-'] .fieldset-wrapper .data-table td,[class^=' adminhtml-rma-'] .grid .col-product_sku,[class^=' adminhtml-rma-'] .grid .col-product_name,.col-grid_segment_name,.adminhtml-catalog-event-index .col-category,[class^=' catalog-search'] .col-search_query,[class^=' catalog-search'] .col-synonym_for,[class^=' catalog-search'] .col-redirect,.adminhtml-urlrewrite-index .col-request_path,.adminhtml-cms-page-index .col-title,.adminhtml-cms-page-index .col-identifier,.adminhtml-cms-hierarchy-index .col-title,.adminhtml-cms-hierarchy-index .col-identifier,.col-banner_name,.adminhtml-widget-instance-index .col-title,.reports-index-search .col-query_text,.adminhtml-rma-item-attribute-index .grid .col-attr-code,.adminhtml-system-store-index .grid td,.catalog-product-attribute-index .col-attr-code,.catalog-product-attribute-index .col-label,.adminhtml-export-index .col-code,.adminhtml-logging-index .grid .col-fullaction,.adminhtml-system-variable-index .grid .col-code,.adminhtml-logging-index .grid .col-info,.dashboard-secondary .dashboard-item tr>td:first-child,.ui-tabs-panel .dashboard-data .col-name,.data-table-td-max .data-table td,[class^=' adminhtml-rma-'] .fieldset-wrapper .accordion .config .data-table td,.data-table-td-max .accordion .config .data-table td,.order-account-information .data-table td,[class^=' adminhtml-rma-'] .rma-request-details .data-table td{overflow:hidden;text-overflow:ellipsis}td.col-period,td.col-date,td.col-date_to,td.col-date_from,td.col-ended_at,td.col-created_at,td.col-updated_at,td.col-customer_since,td.col-session_start_time,td.col-time,td.col-sku,td.col-type,[class^=' adminhtml-rma-'] #rma_items_grid_table .headings th,.adminhtml-process-list .col-action a,.adminhtml-process-list .col-mode{white-space:nowrap}table thead tr th:first-child,table tfoot tr th:first-child,table tfoot tr td:first-child{border-left:0}table thead tr th:last-child,table tfoot tr th:last-child,table tfoot tr td:last-child{border-right:0}.form-inline .grid-actions .label,.form-inline .massaction .label{padding:0;width:auto}.grid .col-action,.grid .col-actions,.grid .col-qty,.grid .col-purchases,.catalog-product-edit .ui-tabs-panel .grid .col-price,.catalog-product-edit .ui-tabs-panel .grid .col-position{width:50px}.grid .col-order-number,.grid .col-real_order_id,.grid .col-invoice-number,.grid .col-increment_id,.grid .col-transaction-id,.grid .col-parent-transaction-id,.grid .col-reference_id,.grid .col-status,.grid .col-price,.grid .col-position,.grid .col-base_grand_total,.grid .col-grand_total,.grid .col-sort_order,.grid .col-carts,.grid .col-priority,.grid .col-severity,.sales-order-create-index .col-in_products,[class^=' reports-'] [class^=col-total],[class^=' reports-'] [class^=col-average],[class^=' reports-'] [class^=col-ref-],[class^=' reports-'] [class^=col-rate],[class^=' reports-'] [class^=col-tax-amount],[class^=' adminhtml-customer-'] .col-required,.adminhtml-rma-item-attribute-index .col-required,[class^=' adminhtml-customer-'] .col-system,.adminhtml-rma-item-attribute-index .col-system,[class^=' adminhtml-customer-'] .col-is_visible,.adminhtml-rma-item-attribute-index .col-is_visible,[class^=' adminhtml-customer-'] .col-sort_order,.adminhtml-rma-item-attribute-index .col-sort_order,.catalog-product-attribute-index [class^=' col-is_'],.catalog-product-attribute-index .col-required,.catalog-product-attribute-index .col-system,.adminhtml-test-index .col-is_listed,[class^=' tests-report-test'] [class^=col-inv-]{width:70px}.grid .col-phone,.sales-order-view .grid .col-period,.sales-order-create-index .col-phone,[class^=' adminhtml-rma-'] .grid .col-product_sku,.adminhtml-rma-edit .col-product,.adminhtml-rma-edit .col-sku,.catalog-product-edit .ui-tabs-panel .grid .col-name,.catalog-product-edit .ui-tabs-panel .grid .col-type,.catalog-product-edit .ui-tabs-panel .grid .col-sku,.customer-index-index .grid .col-customer_since,.customer-index-index .grid .col-billing_country_id,[class^=' customer-index-'] .fieldset-wrapper .grid .col-created_at,[class^=' customer-index-'] .accordion .grid .col-created_at{max-width:70px;width:70px}.sales-order-view .grid .col-name,.sales-order-create-index .data-table .col-product,[class^=' adminhtml-rma-'] .grid .col-name,[class^=' adminhtml-rma-'] .grid .col-product,[class^=' catalog-search'] .col-search_query,[class^=' catalog-search'] .col-synonym_for,[class^=' catalog-search'] .col-redirect,.adminhtml-urlrewrite-index .col-request_path,.reports-report-shopcart-abandoned .grid .col-name,.tax-rule-index .grid .col-title,.adminhtml-rma-item-attribute-index .grid .col-attr-code,.dashboard-secondary .dashboard-item tr>td:first-child{max-width:150px;width:150px}[class^=' sales-order-'] .grid .col-name,.catalog-category-edit .grid .col-name,.adminhtml-catalog-event-index .col-category,.adminhtml-banner-edit .grid .col-name,.reports-report-product-lowstock .grid .col-sku,.newsletter-problem-index .grid .col-name,.newsletter-problem-index .grid .col-subject,.newsletter-problem-index .grid .col-product,.adminhtml-rma-item-attribute-index .grid .col-label,.adminhtml-export-index .col-label,.adminhtml-export-index .col-code,.adminhtml-scheduled-operation-index .grid .col-name,.adminhtml-logging-index .grid .col-fullaction,.test-report-customer-wishlist-wishlist .grid .col-name,.test-report-customer-wishlist-wishlist .grid .col-subject,.test-report-customer-wishlist-wishlist .grid .col-product{max-width:220px;width:220px}.grid .col-period,.grid .col-date,.grid .col-date_to,.grid .col-date_from,.grid .col-ended_at,.grid .col-created_at,.grid .col-updated_at,.grid .col-customer_since,.grid .col-session_start_time,.grid .col-last_activity,.grid .col-email,.grid .col-items_total,.grid .col-firstname,.grid .col-lastname,.grid .col-status-default,.grid .col-websites,.grid .col-time,.grid .col-billing_name,.grid .col-shipping_name,.sales-order-index .grid .col-name,.product-options .grouped-items-table .col-name,.product-options .grouped-items-table .col-sku,[class^=' sales-order-view'] .grid .col-customer_name,[class^=' adminhtml-rma-'] .grid .col-product_name,.catalog-product-index .grid .col-name,.catalog-product-review-index .grid .col-name,.catalog-product-review-index .grid .col-title,.customer-index-edit .ui-tabs-panel .grid .col-name,.review-product-index .grid .col-name,.adminhtml-cms-page-index .col-title,.adminhtml-cms-page-index .col-identifier,.catalog-product-attribute-index .col-attr-code,.catalog-product-attribute-index .col-label,.adminhtml-logging-index .grid .col-info{max-width:110px;width:110px}.grid .col-name,.grid .col-product,.col-banner_name,.adminhtml-widget-instance-index .col-title,[class^=' adminhtml-customer-'] .col-label,.adminhtml-rma-item-attribute-index .col-label,.adminhtml-system-variable-index .grid .col-code,.ui-tabs-panel .dashboard-data .col-name,.adminhtml-test-index .col-label{max-width:370px;width:370px}.col-grid_segment_name,.reports-index-search .col-query_text{max-width:570px;width:570px}[class^=' adminhtml-rma-'] .fieldset-wrapper .data-table td,.reports-report-product-lowstock .grid .col-name,.reports-report-shopcart-product .grid .col-name,.reports-report-review-customer .grid .col-name,[class^=' adminhtml-rma-'] .fieldset-wrapper .accordion .config .data-table td{max-width:670px;width:670px}.reports-report-sales-invoiced .grid .col-period,.reports-report-sales-refunde .grid .col-period,[class^=' tests-report-test'] .grid .col-period{width:auto}.grid .col-select,.grid .col-id,.grid .col-number{width:40px}.sales-order-create-index .grid,.sales-order-create-index .grid-actions,.adminhtml-export-index .grid-actions,.adminhtml-export-index .grid{padding-left:0;padding-right:0}[class^=' adminhtml-rma-'] .col-actions a,[class^=' customer-index-'] .col-action a,.adminhtml-notification-index .col-actions a{display:block;margin:0 0 3px;white-space:nowrap}.data-table-td-max .accordion .config .data-table td,.order-account-information .data-table td,[class^=' adminhtml-rma-'] .rma-request-details .data-table td{max-width:250px;width:250px}.catalog-product-edit .ui-tabs-panel .grid .hor-scroll,.catalog-product-index .grid .hor-scroll,.review-product-index .grid .hor-scroll,.adminhtml-rma-edit .hor-scroll{overflow-x:auto}.add-clearer:after,.massaction:after,.navigation>ul:after{content:"";display:table;clear:both}.test-content{width:calc(20px + 100*0.2)}.test-content:before{content:'.test {\A ' attr(data-attribute) ': 0.2em;' '\A content:\'';white-space:pre}.test-content:after{content:' Test\';\A}' "\A" '\A.test + .test._other ~ ul > li' " {\A height: @var;\A content: ' + ';\A}";white-space:pre}.test-content-calc{width:calc((100%/12*2) - 10px)}.test-svg-xml-image{background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" viewBox="0 0 38 40"><style>.st0{fill:none;stroke:%23ffffff;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;}</style><circle cx="14.7" cy="14.7" r="13.7" class="st0"/><path d="M23.9 24.7L37 39" class="st0"/></svg>') no-repeat left center} \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/theme/web/css/styles.css b/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/theme/web/css/styles.css index 8b1d0fae6d96b..90ca42321c921 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/theme/web/css/styles.css +++ b/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/theme/web/css/styles.css @@ -1000,15 +1000,13 @@ fieldset[disabled] .pager .action-next { } @font-face { font-family: 'icons-blank-theme'; - src: url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot'); - src: url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot?#iefix') format('embedded-opentype'), url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2') format('woff2'), url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff') format('woff'), url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.ttf') format('truetype'), url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.svg#icons-blank-theme') format('svg'); + src: url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2') format('woff2'), url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff') format('woff'); font-weight: normal; font-style: normal; } @font-face { font-family: 'icons-blank-theme'; - src: url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot'); - src: url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot?#iefix') format('embedded-opentype'), url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2') format('woff2'), url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff') format('woff'), url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.ttf') format('truetype'); + src: url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2') format('woff2'), url('../fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff') format('woff'); font-weight: normal; font-style: normal; } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/InvoiceEmailSenderHandlerTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/InvoiceEmailSenderHandlerTest.php new file mode 100644 index 0000000000000..332092946c4d6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/InvoiceEmailSenderHandlerTest.php @@ -0,0 +1,103 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Model; + +use Magento\Config\Model\Config; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Store\Model\ScopeInterface; + +class InvoiceEmailSenderHandlerTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Sales\Model\ResourceModel\Order\Invoice\Collection + */ + private $entityCollection; + + /** + * @var \Magento\Sales\Model\EmailSenderHandler + */ + private $emailSender; + + protected function setUp() + { + /** @var \Magento\Sales\Model\Order\Email\Container\InvoiceIdentity $invoiceIdentity */ + $invoiceIdentity = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\Order\Email\Container\InvoiceIdentity::class + ); + /** @var \Magento\Sales\Model\Order\Email\Sender\InvoiceSender $invoiceSender */ + $invoiceSender = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create( + \Magento\Sales\Model\Order\Email\Sender\InvoiceSender::class, + [ + 'identityContainer' => $invoiceIdentity, + ] + ); + $entityResource = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Sales\Model\ResourceModel\Order\Invoice::class); + $this->entityCollection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\ResourceModel\Order\Invoice\Collection::class + ); + $this->emailSender = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\EmailSenderHandler::class, + [ + 'emailSender' => $invoiceSender, + 'entityResource' => $entityResource, + 'entityCollection' => $this->entityCollection, + 'identityContainer' => $invoiceIdentity, + ] + ); + } + + /** + * @magentoAppIsolation enabled + * @magentoDbIsolation disabled + * @magentoDataFixture Magento/Sales/_files/invoice_list_different_stores.php + */ + public function testInvoiceEmailSenderExecute() + { + $expectedResult = 1; + + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + /** @var Config $defConfig */ + $defConfig = $objectManager->create(Config::class); + $defConfig->setScope(ScopeConfigInterface::SCOPE_TYPE_DEFAULT); + $defConfig->setDataByPath('sales_email/general/async_sending', 1); + $defConfig->save(); + + /** @var Config $storeConfig */ + $storeConfig = $objectManager->create(Config::class); + $storeConfig->setScope(ScopeInterface::SCOPE_STORES); + $storeConfig->setStore('fixture_second_store'); + $storeConfig->setDataByPath('sales_email/invoice/enabled', 0); + $storeConfig->save(); + + $sendCollection = clone $this->entityCollection; + $sendCollection->addFieldToFilter('send_email', ['eq' => 1]); + $sendCollection->addFieldToFilter('email_sent', ['null' => true]); + + $this->emailSender->sendEmails(); + + $this->assertCount($expectedResult, $sendCollection->getItems()); + } + + /** + * @inheritdoc + * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Exception + */ + protected function tearDown() + { + /** @var \Magento\Config\Model\Config $defConfig */ + $defConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Config\Model\Config::class); + $defConfig->setScope(\Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT); + $defConfig->setDataByPath('sales_email/general/async_sending', 0); + $defConfig->save(); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list.php index 669b1a4268388..b5a4f5fa1eb0b 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list.php @@ -53,9 +53,9 @@ ], ]; -/** @var array $creditMemoData */ +/** @var array $invoiceData */ foreach ($invoices as $invoiceData) { - /** @var \Magento\Sales\Model\Order\Creditmemo $creditMemo */ + /** @var \Magento\Sales\Model\Order\Invoice $invoice */ $invoice = $objectManager->create(\Magento\Sales\Model\Order\Invoice::class); $invoice ->setData($invoiceData) diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list_different_stores.php b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list_different_stores.php new file mode 100644 index 0000000000000..e6a1947b72edd --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list_different_stores.php @@ -0,0 +1,132 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require 'default_rollback.php'; +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple.php'; +/** @var \Magento\Catalog\Model\Product $product */ + +require __DIR__ . '/../../../Magento/Store/_files/second_store.php'; + +$addressData = include __DIR__ . '/address_data.php'; + +$store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Store\Model\Store::class); +$secondStoreId = $store->load('fixture_second_store')->getId(); + +$orders = [ + [ + 'increment_id' => '100000002', + 'state' => \Magento\Sales\Model\Order::STATE_NEW, + 'status' => 'processing', + 'grand_total' => 120.00, + 'subtotal' => 120.00, + 'base_grand_total' => 120.00, + 'store_id' => 0, + 'website_id' => 1, + ], + [ + 'increment_id' => '100000003', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'processing', + 'grand_total' => 140.00, + 'base_grand_total' => 140.00, + 'subtotal' => 140.00, + 'store_id' => 1, + 'website_id' => 0, + ], + [ + 'increment_id' => '100000004', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'closed', + 'grand_total' => 140.00, + 'base_grand_total' => 140.00, + 'subtotal' => 140.00, + 'store_id' => $secondStoreId, + 'website_id' => 1, + ], +]; + +/** @var \Magento\Sales\Model\Order\Address $billingAddress */ +$billingAddress = $objectManager->create(\Magento\Sales\Model\Order\Address::class, ['data' => $addressData]); +$billingAddress->setAddressType('billing'); + +/** @var \Magento\Sales\Model\Order\Address $shippingAddress */ +$shippingAddress = clone $billingAddress; +$shippingAddress->setId(null)->setAddressType('shipping'); + +/** @var \Magento\Sales\Model\Order\Payment $payment */ +$payment = $objectManager->create(\Magento\Sales\Model\Order\Payment::class); +$payment->setMethod('checkmo'); +$payment->setAdditionalInformation('last_trans_id', '11122'); +$payment->setAdditionalInformation('metadata', [ + 'type' => 'free', + 'fraudulent' => false, +]); + +/** @var \Magento\Sales\Model\Order\Item $orderItem */ +$orderItem = $objectManager->create(\Magento\Sales\Model\Order\Item::class); +$orderItem->setProductId($product->getId())->setQtyOrdered(2); +$orderItem->setBasePrice($product->getPrice()); +$orderItem->setPrice($product->getPrice()); +$orderItem->setRowTotal($product->getPrice()); +$orderItem->setProductType('simple'); + +/** @var \Magento\Sales\Api\InvoiceManagementInterface $orderService */ +$orderService = \Magento\TestFramework\ObjectManager::getInstance()->create( + \Magento\Sales\Api\InvoiceManagementInterface::class +); + +/** @var \Magento\Sales\Api\OrderRepositoryInterface $orderRepository */ +$orderRepository = $objectManager->create(\Magento\Sales\Api\OrderRepositoryInterface::class); + +foreach ($orders as $orderFixture) { + /** @var \Magento\Sales\Model\Order $order */ + $order = $objectManager->create(\Magento\Sales\Model\Order::class); + $order->setData($orderFixture); + $order->setIncrementId( + $orderFixture['increment_id'] + )->setStoreId( + $orderFixture['store_id'] + )->setState( + $orderFixture['state'] + )->setStatus( + $orderFixture['status'] + )->setSubtotal( + $orderFixture['subtotal'] + )->setGrandTotal( + $orderFixture['grand_total'] + )->setBaseSubtotal( + $orderFixture['subtotal'] + )->setBaseGrandTotal( + $orderFixture['base_grand_total'] + )->setCustomerIsGuest( + true + )->setCustomerEmail( + 'customer@null.com' + )->setBillingAddress( + clone $billingAddress + )->setShippingAddress( + clone $shippingAddress + )->addItem( + clone $orderItem + )->setPayment( + clone $payment + ); + + $orderRepository->save($order); + + /** @var \Magento\Sales\Model\Order\Invoice $invoice */ + $invoice = $orderService->prepareInvoice($order, $order->getItems()); + $invoice->register(); + $invoice->setSendEmail(1); + $invoice->setStoreId($orderFixture['store_id']); + $order = $invoice->getOrder(); + $order->setIsInProcess(true); + $transactionSave = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Framework\DB\Transaction::class); + $transactionSave->addObject($invoice)->addObject($order)->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list_different_stores_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list_different_stores_rollback.php new file mode 100644 index 0000000000000..803a69cabf77b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list_different_stores_rollback.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require 'default_rollback.php'; +require __DIR__ . '/../../../Magento/Store/_files/second_store_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Condition/ProductTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Condition/ProductTest.php index 02a4ba4c282a0..98826adeb2147 100644 --- a/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Condition/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Condition/ProductTest.php @@ -58,6 +58,28 @@ public function testValidateCategorySalesRuleIncludesChildren($categoryId, $expe $this->assertEquals($expectedResult, $rule->validate($quote)); } + /** + * @magentoDbIsolation disabled + * @magentoDataFixture Magento/Bundle/_files/order_item_with_bundle_and_options.php + * @magentoDataFixture Magento/SalesRule/_files/rules_sku_exclude.php + * + * @return void + */ + public function testValidateSalesRuleExcludesBundleChildren(): void + { + // Load the quote that contains a child of a bundle product + /** @var \Magento\Quote\Model\Quote $quote */ + $quote = $this->objectManager->create(\Magento\Quote\Model\Quote::class) + ->load('test_cart_with_bundle_and_options', 'reserved_order_id'); + + // Load the SalesRule looking for excluding products with selected sku + /** @var $rule \Magento\SalesRule\Model\Rule */ + $rule = $this->objectManager->get(\Magento\Framework\Registry::class) + ->registry('_fixture/Magento_SalesRule_Sku_Exclude'); + + $this->assertEquals(false, $rule->validate($quote)); + } + /** * @return array */ diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_sku_exclude.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_sku_exclude.php new file mode 100644 index 0000000000000..9d88fe48ae111 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_sku_exclude.php @@ -0,0 +1,79 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +/** @var \Magento\Eav\Api\AttributeRepositoryInterface $repository */ +$repository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Eav\Api\AttributeRepositoryInterface::class); + +/** @var \Magento\Eav\Api\Data\AttributeInterface $skuAttribute */ +$skuAttribute = $repository->get( + 'catalog_product', + 'sku' +); +$data = $skuAttribute->getData(); +$data['is_used_for_promo_rules'] = 1; +$skuAttribute->setData($data); +$skuAttribute->save(); + +/** @var \Magento\SalesRule\Model\Rule $rule */ +$salesRule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class); +$salesRule->setData( + [ + 'name' => '20% Off', + 'is_active' => 1, + 'customer_group_ids' => [\Magento\Customer\Model\GroupManagement::NOT_LOGGED_IN_ID], + 'coupon_type' => \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON, + 'simple_action' => 'by_percent', + 'discount_amount' => 20, + 'discount_step' => 0, + 'stop_rules_processing' => 1, + 'website_ids' => [ + \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Store\Model\StoreManagerInterface::class + )->getWebsite()->getId(), + ], + ] +); + +$salesRule->getConditions()->loadArray([ + 'type' => \Magento\SalesRule\Model\Rule\Condition\Combine::class, + 'attribute' => null, + 'operator' => null, + 'value' => '1', + 'is_value_processed' => null, + 'aggregator' => 'all', + 'conditions' => + [ + [ + 'type' => \Magento\SalesRule\Model\Rule\Condition\Product\Found::class, + 'attribute' => null, + 'operator' => null, + 'value' => '1', + 'is_value_processed' => null, + 'aggregator' => 'all', + 'conditions' => + [ + [ + 'type' => \Magento\SalesRule\Model\Rule\Condition\Product::class, + 'attribute' => 'sku', + 'operator' => '!=', + 'value' => 'product-bundle', + 'is_value_processed' => false, + ], + ], + ], + ], +]); + +$salesRule->save(); + +/** @var Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +$registry->unregister('_fixture/Magento_SalesRule_Sku_Exclude'); +$registry->register('_fixture/Magento_SalesRule_Sku_Exclude', $salesRule); diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_sku_exclude_rollback.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_sku_exclude_rollback.php new file mode 100644 index 0000000000000..79ec3259fd86a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_sku_exclude_rollback.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +/** @var \Magento\Eav\Api\AttributeRepositoryInterface $repository */ +$repository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Eav\Api\AttributeRepositoryInterface::class); + +/** @var \Magento\Eav\Api\Data\AttributeInterface $skuAttribute */ +$skuAttribute = $repository->get( + 'catalog_product', + 'sku' +); +$data = $skuAttribute->getData(); +$data['is_used_for_promo_rules'] = 0; +$skuAttribute->setData($data); +$skuAttribute->save(); + +/** @var Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +/** @var Magento\SalesRule\Model\Rule $rule */ +$rule = $registry->registry('_fixture/Magento_SalesRule_Sku_Exclude'); + +$rule->delete(); diff --git a/dev/tests/integration/testsuite/Magento/Setup/Declaration/WhitelistDeclarationTest.php b/dev/tests/integration/testsuite/Magento/Setup/Declaration/WhitelistDeclarationTest.php new file mode 100644 index 0000000000000..6b92e687284db --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Setup/Declaration/WhitelistDeclarationTest.php @@ -0,0 +1,162 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Setup\Declaration; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\App\Utility\Files; +use Magento\Framework\Component\ComponentRegistrar; +use Magento\Framework\Component\ComponentRegistrarInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\Dto\Constraint; +use Magento\Framework\Setup\Declaration\Schema\Dto\Index; +use Magento\Framework\Setup\Declaration\Schema\SchemaConfigInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; + +/** + * Class WhitelistDeclarationTest + */ +class WhitelistDeclarationTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ComponentRegistrarInterface + */ + private $componentRegistrar; + + /** + * @var SchemaConfigInterface + */ + private $schemaConfig; + + public function setUp() + { + /** @var ObjectManagerInterface|ObjectManager $objectManager */ + $objectManager = Bootstrap::getObjectManager(); + $resourceConnection = $objectManager->create(ResourceConnection::class); + $objectManager->removeSharedInstance(ResourceConnection::class); + $objectManager->addSharedInstance($resourceConnection, ResourceConnection::class); + $this->componentRegistrar = $objectManager->get(ComponentRegistrarInterface::class); + $this->schemaConfig = $objectManager->create(SchemaConfigInterface::class); + } + + /** + * Checks that all declared table elements also declared into whitelist declaration. + * + * @appIsolation + * @throws \Exception + */ + public function testConstraintsAndIndexesAreWhitelisted() + { + $undeclaredElements = []; + $resultMessage = "New table elements that do not exist in the whitelist declaration:\n"; + $whitelistTables = $this->getWhiteListTables(); + $declarativeSchema = $this->schemaConfig->getDeclarationConfig(); + + foreach ($declarativeSchema->getTables() as $schemaTable) { + $tableNameWithoutPrefix = $schemaTable->getNameWithoutPrefix(); + foreach ($schemaTable->getConstraints() as $constraint) { + $constraintNameWithoutPrefix = $constraint->getNameWithoutPrefix(); + if (isset($whitelistTables[$tableNameWithoutPrefix][Constraint::TYPE][$constraintNameWithoutPrefix])) { + continue; + } + + $undeclaredElements[$tableNameWithoutPrefix][Constraint::TYPE][] = $constraintNameWithoutPrefix; + } + + foreach ($schemaTable->getIndexes() as $index) { + $indexNameWithoutPrefix = $index->getNameWithoutPrefix(); + if (isset($whitelistTables[$tableNameWithoutPrefix][Index::TYPE][$indexNameWithoutPrefix])) { + continue; + } + + $undeclaredElements[$tableNameWithoutPrefix][Index::TYPE][] = $indexNameWithoutPrefix; + } + } + + $undeclaredElements = $this->filterUndeclaredElements($undeclaredElements); + + if (!empty($undeclaredElements)) { + $resultMessage .= json_encode($undeclaredElements, JSON_PRETTY_PRINT); + } + + $this->assertEmpty($undeclaredElements, $resultMessage); + } + + /** + * Excludes ignored elements from the list of undeclared table elements. + * + * @param array $undeclaredElements + * @return array + */ + private function filterUndeclaredElements(array $undeclaredElements): array + { + $files = Files::getFiles([__DIR__ . '/_files/ignore_whitelisting'], '*.json'); + $ignoredElements = []; + foreach ($files as $filePath) { + $ignoredElements = array_merge_recursive( + $ignoredElements, + json_decode(file_get_contents($filePath), true) + ); + } + + return $this->arrayRecursiveDiff($undeclaredElements, $ignoredElements); + } + + /** + * Performs a recursive comparison of two arrays. + * + * @param array $array1 + * @param array $array2 + * @return array + */ + private function arrayRecursiveDiff(array $array1, array $array2): array + { + $diffResult = []; + + foreach ($array1 as $key => $value) { + if (array_key_exists($key, $array2)) { + if (is_array($value)) { + $recursiveDiffResult = $this->arrayRecursiveDiff($value, $array2[$key]); + if (count($recursiveDiffResult)) { + $diffResult[$key] = $recursiveDiffResult; + } + } else { + if (!in_array($value, $array2)) { + $diffResult[] = $value; + } + } + } else { + $diffResult[$key] = $value; + } + } + + return $diffResult; + } + + /** + * @return array + */ + private function getWhiteListTables(): array + { + $whiteListTables = []; + + foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $path) { + $whiteListPath = $path . DIRECTORY_SEPARATOR . 'etc' . + DIRECTORY_SEPARATOR . 'db_schema_whitelist.json'; + + if (file_exists($whiteListPath)) { + $whiteListTables = array_replace_recursive( + $whiteListTables, + json_decode(file_get_contents($whiteListPath), true) + ); + } + } + + return $whiteListTables; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Setup/Declaration/_files/ignore_whitelisting/ce.json b/dev/tests/integration/testsuite/Magento/Setup/Declaration/_files/ignore_whitelisting/ce.json new file mode 100644 index 0000000000000..881481ab407bc --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Setup/Declaration/_files/ignore_whitelisting/ce.json @@ -0,0 +1,7 @@ +{ + "patch_list": { + "constraint": [ + "PRIMARY" + ] + } +} diff --git a/dev/tests/integration/testsuite/Magento/Signifyd/Observer/PlaceOrderTest.php b/dev/tests/integration/testsuite/Magento/Signifyd/Observer/PlaceOrderTest.php index d4204314453e5..e547187be5ed7 100644 --- a/dev/tests/integration/testsuite/Magento/Signifyd/Observer/PlaceOrderTest.php +++ b/dev/tests/integration/testsuite/Magento/Signifyd/Observer/PlaceOrderTest.php @@ -12,10 +12,17 @@ use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Signifyd\Api\CaseCreationServiceInterface; +use Magento\Store\Api\StoreRepositoryInterface; +use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\Helper\Bootstrap; use PHPUnit\Framework\MockObject_MockObject as MockObject; use Psr\Log\LoggerInterface; +/** + * Test for Magento\Signifyd\Observer\PlaceOrderTest class. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class PlaceOrderTest extends \PHPUnit\Framework\TestCase { /** @@ -105,7 +112,46 @@ public function testExecute() $event = $this->objectManager->create( Event::class, [ - 'data' => ['order' => $order] + 'data' => ['order' => $order], + ] + ); + + /** @var Observer $observer */ + $observer = $this->objectManager->get(Observer::class); + $observer->setEvent($event); + + $this->placeOrder->execute($observer); + } + + /** + * Signifyd is enabled for default store. + * Checks a test case when order placed with website where signifyd is disabled. + * + * @return void + * @covers \Magento\Signifyd\Observer\PlaceOrder::execute + * @magentoDataFixture Magento/Signifyd/_files/order_with_customer_and_two_simple_products.php + * @magentoDataFixture Magento/Signifyd/_files/website_configuration.php + */ + public function testExecuteWithWebsiteConfiguration(): void + { + /** @var StoreRepositoryInterface $storeRepository */ + $storeRepository = $this->objectManager->get(StoreRepositoryInterface::class); + $store = $storeRepository->get('test_second_store'); + + /** @var StoreManagerInterface $storeManager */ + $storeManager = $this->objectManager->get(StoreManagerInterface::class); + $storeManager->setCurrentStore($store->getId()); + + $order = $this->getOrder('100000001'); + $order->setStoreId($store->getId()); + + $this->creationService->expects(self::never()) + ->method('createForOrder'); + + $event = $this->objectManager->create( + Event::class, + [ + 'data' => ['order' => $order], ] ); diff --git a/dev/tests/integration/testsuite/Magento/Signifyd/_files/order_with_customer_and_two_simple_products.php b/dev/tests/integration/testsuite/Magento/Signifyd/_files/order_with_customer_and_two_simple_products.php index 8991825c9381e..49a0a2d33e236 100644 --- a/dev/tests/integration/testsuite/Magento/Signifyd/_files/order_with_customer_and_two_simple_products.php +++ b/dev/tests/integration/testsuite/Magento/Signifyd/_files/order_with_customer_and_two_simple_products.php @@ -10,7 +10,7 @@ use Magento\Sales\Api\OrderRepositoryInterface; use Magento\TestFramework\Helper\Bootstrap; -require __DIR__ . '/../../../Magento/Catalog/_files/multiple_products.php'; +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple.php'; require __DIR__ . '/../../../Magento/Customer/_files/customer.php'; require __DIR__ . '/store.php'; @@ -36,33 +36,28 @@ ->setCcExpMonth('01') ->setCcExpYear('21'); -/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ -$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); - -$product1 = $productRepository->get('simple1'); /** @var Item $orderItem */ $orderItem1 = $objectManager->create(Item::class); -$orderItem1->setProductId($product1->getId()) - ->setSku($product1->getSku()) - ->setName($product1->getName()) +$orderItem1->setProductId($product->getId()) + ->setSku($product->getSku()) + ->setName($product->getName()) ->setQtyOrdered(1) - ->setBasePrice($product1->getPrice()) - ->setPrice($product1->getPrice()) - ->setRowTotal($product1->getPrice()) - ->setProductType($product1->getTypeId()); + ->setBasePrice($product->getPrice()) + ->setPrice($product->getPrice()) + ->setRowTotal($product->getPrice()) + ->setProductType($product->getTypeId()); -$product2 = $productRepository->get('simple2'); /** @var Item $orderItem */ $orderItem2 = $objectManager->create(Item::class); -$orderItem2->setProductId($product2->getId()) - ->setSku($product2->getSku()) - ->setName($product2->getName()) - ->setPrice($product2->getPrice()) +$orderItem2->setProductId($product->getId()) + ->setSku('simple2') + ->setName('Simple product') + ->setPrice(100) ->setQtyOrdered(2) - ->setBasePrice($product2->getPrice()) - ->setPrice($product2->getPrice()) - ->setRowTotal($product2->getPrice()) - ->setProductType($product2->getTypeId()); + ->setBasePrice($product->getPrice()) + ->setPrice($product->getPrice()) + ->setRowTotal($product->getPrice()) + ->setProductType($product->getTypeId()); $orderAmount = 100; $customerEmail = $billingAddress->getEmail(); diff --git a/dev/tests/integration/testsuite/Magento/Signifyd/_files/website_configuration.php b/dev/tests/integration/testsuite/Magento/Signifyd/_files/website_configuration.php new file mode 100644 index 0000000000000..e53b0431503e7 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Signifyd/_files/website_configuration.php @@ -0,0 +1,67 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Config\Model\Config; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Store\Model\ResourceModel\Store as StoreResourceModel; +use Magento\Store\Model\ResourceModel\Website as WebsiteResourceModel; +use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Store\Model\Website; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var $website Website */ +$website = $objectManager->create(Website::class); +$website->setData(['code' => 'test_website', 'name' => 'Test Website', 'default_group_id' => '1', 'is_default' => '0']); +$websiteResourceModel = $objectManager->create(WebsiteResourceModel::class); +$websiteResourceModel->save($website); + +$websiteId = $website->getId(); +$store = $objectManager->create(Store::class); +$groupId = Bootstrap::getObjectManager()->get(StoreManagerInterface::class) + ->getWebsite() + ->getDefaultGroupId(); +$store->setCode('test_second_store') + ->setWebsiteId($websiteId) + ->setGroupId($groupId) + ->setName('Test Second Store') + ->setSortOrder(10) + ->setIsActive(1); +$storeResourceModel = $objectManager->create(StoreResourceModel::class); +$storeResourceModel->save($store); + +/* Refresh stores memory cache */ +$objectManager->get(StoreManagerInterface::class)->reinitStores(); + +$processConfigData = function (Config $config, array $data) { + foreach ($data as $key => $value) { + $config->setDataByPath($key, $value); + $config->save(); + } +}; + +// save signifyd configuration for the default scope +$configData = [ + 'fraud_protection/signifyd/active' => '1', +]; +/** @var Config $defConfig */ +$defConfig = $objectManager->create(Config::class); +$defConfig->setScope(ScopeConfigInterface::SCOPE_TYPE_DEFAULT); +$processConfigData($defConfig, $configData); + +// save signifyd website config data +$websiteConfigData = [ + 'fraud_protection/signifyd/active' => '0', +]; +/** @var Config $websiteConfig */ +$websiteConfig = $objectManager->create(Config::class); +$websiteConfig->setScope(ScopeInterface::SCOPE_WEBSITES); +$websiteConfig->setWebsite($websiteId); +$processConfigData($websiteConfig, $websiteConfigData); diff --git a/dev/tests/integration/testsuite/Magento/Signifyd/_files/website_configuration_rollback.php b/dev/tests/integration/testsuite/Magento/Signifyd/_files/website_configuration_rollback.php new file mode 100644 index 0000000000000..9b731813fea3b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Signifyd/_files/website_configuration_rollback.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Config\Storage\WriterInterface; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\Store; +use Magento\Store\Model\Website; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +$deleteConfigData = function (WriterInterface $writer, $scope, $scopeId) { + $configData = [ + 'fraud_protection/signifyd/active', + ]; + foreach ($configData as $path) { + $writer->delete($path, $scope, $scopeId); + } +}; + +/** @var WriterInterface $configWriter */ +$configWriter = $objectManager->get(WriterInterface::class); +$deleteConfigData($configWriter, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null); + +/** @var WebsiteRepositoryInterface $websiteRepository */ +$websiteRepository = $objectManager->get(WebsiteRepositoryInterface::class); +$website = $websiteRepository->get('test_website'); +$deleteConfigData($configWriter, ScopeInterface::SCOPE_WEBSITES, $website->getId()); + +$website = $objectManager->create(Website::class); +/** @var $website Website */ +if ($website->load('test_website', 'code')->getId()) { + $website->delete(); +} +$store = $objectManager->create(Store::class); +if ($store->load('test_second_store', 'code')->getId()) { + $store->delete(); +} diff --git a/dev/tests/integration/testsuite/Magento/Store/Controller/Store/SwitchActionTest.php b/dev/tests/integration/testsuite/Magento/Store/Controller/Store/SwitchActionTest.php index dfd979f03c576..bc8ca2ba07a80 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Controller/Store/SwitchActionTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Controller/Store/SwitchActionTest.php @@ -48,8 +48,5 @@ protected function changeStoreCode($from, $to) $store->load($from, 'code'); $store->setCode($to); $store->save(); - /** @var \Magento\Store\Model\StoreManagerInterface $storeManager */ - $storeManager = $this->_objectManager->get(\Magento\Store\Model\StoreManagerInterface::class); - $storeManager->reinitStores(); } } diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/core_fixturestore.php b/dev/tests/integration/testsuite/Magento/Store/_files/core_fixturestore.php index e3971ad912a78..a4a640a24de50 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/core_fixturestore.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/core_fixturestore.php @@ -21,9 +21,6 @@ ->setSortOrder(10) ->setIsActive(1); $store->save(); - - /* Refresh stores memory cache */ - Bootstrap::getObjectManager()->get(\Magento\Store\Model\StoreManagerInterface::class)->reinitStores(); } //if test using this fixture relies on full text functionality it is required to explicitly perform re-indexation diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/core_fixturestore_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/core_fixturestore_rollback.php index d6b9e1d9abc70..95d13111e6193 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/core_fixturestore_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/core_fixturestore_rollback.php @@ -23,6 +23,3 @@ $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); - -/* Refresh stores memory cache */ -$objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore.php b/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore.php index 139f36ca3c9d6..3cb429822eb9a 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore.php @@ -27,8 +27,3 @@ $store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); $store->setCode('thirdstore')->setName('Third Store')->setSortOrder(10)->setIsActive(1); $store->save(); - -/* Refresh stores memory cache */ -\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Store\Model\StoreManagerInterface::class -)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore_rollback.php index 1799845aced48..19d064bb79834 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/core_second_third_fixturestore_rollback.php @@ -35,8 +35,3 @@ $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); - -/* Refresh stores memory cache */ -\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Store\Model\StoreManagerInterface::class -)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/fixture_store_with_catalogsearch_index.php b/dev/tests/integration/testsuite/Magento/Store/_files/fixture_store_with_catalogsearch_index.php index 064dfbcdbe2be..d5fd725e7df4d 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/fixture_store_with_catalogsearch_index.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/fixture_store_with_catalogsearch_index.php @@ -21,11 +21,4 @@ ->setSortOrder(10) ->setIsActive(1); $store->save(); - - Bootstrap::getObjectManager() - ->get(\Magento\Framework\Event\ManagerInterface::class) - ->dispatch('store_add', ['store' => $store]); - - /* Refresh stores memory cache */ - Bootstrap::getObjectManager()->get(\Magento\Store\Model\StoreManagerInterface::class)->reinitStores(); } diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/fixture_store_with_catalogsearch_index_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/fixture_store_with_catalogsearch_index_rollback.php index 8a69f83882ade..251635dcff09f 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/fixture_store_with_catalogsearch_index_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/fixture_store_with_catalogsearch_index_rollback.php @@ -20,8 +20,3 @@ $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); - -/* Refresh stores memory cache */ -\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Store\Model\StoreManagerInterface::class -)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php index a97457a581393..af008a28d611b 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php @@ -6,6 +6,7 @@ * See COPYING.txt for license details. */ +/** @var \Magento\Store\Model\Store $store */ $store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); if (!$store->load('fixture_second_store', 'code')->getId()) { $websiteId = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( @@ -30,8 +31,3 @@ ); $store->save(); } - -/* Refresh stores memory cache */ -\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Store\Model\StoreManagerInterface::class -)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php index 4fc5d3b65b270..56ba31fad4ed2 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_rollback.php @@ -20,8 +20,3 @@ $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); - -/* Refresh stores memory cache */ -\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Store\Model\StoreManagerInterface::class -)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_website_with_two_stores.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_website_with_two_stores.php index 078b590132f06..016acca1e8e04 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/second_website_with_two_stores.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_website_with_two_stores.php @@ -51,10 +51,6 @@ ); $store->save(); } -/* Refresh stores memory cache */ -\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Store\Model\StoreManagerInterface::class -)->reinitStores(); /* Refresh CatalogSearch index */ /** @var \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry */ diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_website_with_two_stores_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_website_with_two_stores_rollback.php index b97dc4dd40bd9..eef8cf960944c 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/second_website_with_two_stores_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_website_with_two_stores_rollback.php @@ -27,8 +27,3 @@ $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); - -/* Refresh stores memory cache */ -\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Store\Model\StoreManagerInterface::class -)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/store.php b/dev/tests/integration/testsuite/Magento/Store/_files/store.php index e49d16e2ede68..94ea5a9364b87 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/store.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/store.php @@ -37,6 +37,3 @@ $store->save(); } } -$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -/* Refresh stores memory cache */ -$objectManager->get('Magento\Store\Model\StoreManagerInterface')->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/store_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/store_rollback.php index 3b437f08c8c33..8289244d6581a 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/store_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/store_rollback.php @@ -31,8 +31,3 @@ $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); - -/* Refresh stores memory cache */ -\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Store\Model\StoreManagerInterface::class -)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php b/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php index 7a20eee640585..13a43d0a710a3 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php @@ -44,9 +44,6 @@ $store->save(); } -/* Refresh stores memory cache */ -$objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)->reinitStores(); - //Setting up allowed countries $configResource = $objectManager->get(\Magento\Config\Model\ResourceModel\Config::class); //Allowed countries for default website. diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php new file mode 100644 index 0000000000000..969d9530ae542 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php @@ -0,0 +1,213 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Swatches\Controller\Adminhtml\Product; + +use Magento\Framework\Exception\LocalizedException; + +/** + * Test for product attribute save controller. + * + * @magentoAppArea adminhtml + * @magentoDbIsolation enabled + */ +class AttributeTest extends \Magento\TestFramework\TestCase\AbstractBackendController +{ + /** + * Generate random hex color. + * + * @return string + */ + private function getRandomColor() : string + { + return '#' . str_pad(dechex(mt_rand(0, 0xFFFFFF)), 6, '0', STR_PAD_LEFT); + } + + /** + * Get visual swatches data set. + * + * @param int $optionsCount + * @return array + */ + private function getSwatchVisualDataSet(int $optionsCount) : array + { + $optionsData = []; + $expectedOptionsLabels = []; + for ($i = 0; $i < $optionsCount; $i++) { + $order = $i + 1; + $expectedOptionLabelOnStoreView = "value_{$i}_store_1"; + $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; + $optionsData []= "optionvisual[order][option_{$i}]={$order}"; + $optionsData []= "defaultvisual[]=option_{$i}"; + $optionsData []= "swatchvisual[value][option_{$i}]={$this->getRandomColor()}"; + $optionsData []= "optionvisual[value][option_{$i}][0]=value_{$i}_admin"; + $optionsData []= "optionvisual[value][option_{$i}][1]={$expectedOptionLabelOnStoreView}"; + $optionsData []= "optionvisual[delete][option_{$i}]="; + } + $optionsData []= "visual_swatch_validation="; + $optionsData []= "visual_swatch_validation_unique="; + return [ + 'attribute_data' => array_merge_recursive( + [ + 'serialized_swatch_values' => json_encode($optionsData), + ], + $this->getAttributePreset(), + [ + 'frontend_input' => 'swatch_visual' + ] + ), + 'expected_options_count' => $optionsCount + 1, + 'expected_store_labels' => $expectedOptionsLabels + ]; + } + + /** + * Get text swatches data set. + * + * @param int $optionsCount + * @return array + */ + private function getSwatchTextDataSet(int $optionsCount) : array + { + $optionsData = []; + $expectedOptionsLabels = []; + for ($i = 0; $i < $optionsCount; $i++) { + $order = $i + 1; + $expectedOptionLabelOnStoreView = "value_{$i}_store_1"; + $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; + $optionsData []= "optiontext[order][option_{$i}]={$order}"; + $optionsData []= "defaulttext[]=option_{$i}"; + $optionsData []= "swatchtext[value][option_{$i}]=x{$i}"; + $optionsData []= "optiontext[value][option_{$i}][0]=value_{$i}_admin"; + $optionsData []= "optiontext[value][option_{$i}][1]={$expectedOptionLabelOnStoreView}"; + $optionsData []= "optiontext[delete][option_{$i}]="; + } + $optionsData []= "text_swatch_validation="; + $optionsData []= "text_swatch_validation_unique="; + return [ + 'attribute_data' => array_merge_recursive( + [ + 'serialized_swatch_values' => json_encode($optionsData), + ], + $this->getAttributePreset(), + [ + 'frontend_input' => 'swatch_text' + ] + ), + 'expected_options_count' => $optionsCount + 1, + 'expected_store_labels' => $expectedOptionsLabels + ]; + } + + /** + * Get data preset for new attribute. + * + * @return array + */ + private function getAttributePreset() : array + { + return [ + 'serialized_options' => '[]', + 'form_key' => 'XxtpPYjm2YPYUlAt', + 'frontend_label' => [ + 0 => 'asdasd', + 1 => '', + 2 => '', + ], + 'is_required' => '0', + 'update_product_preview_image' => '0', + 'use_product_image_for_swatch' => '0', + 'is_global' => '0', + 'default_value_text' => '512', + 'default_value_yesno' => '1', + 'default_value_date' => '1/1/70', + 'default_value_textarea' => '512', + 'is_unique' => '0', + 'is_used_in_grid' => '1', + 'is_visible_in_grid' => '1', + 'is_filterable_in_grid' => '1', + 'is_searchable' => '0', + 'is_comparable' => '0', + 'is_filterable' => '0', + 'is_filterable_in_search' => '0', + 'position' => '0', + 'is_used_for_promo_rules' => '0', + 'is_html_allowed_on_front' => '1', + 'is_visible_on_front' => '0', + 'used_in_product_listing' => '0', + 'used_for_sort_by' => '0', + 'attribute_code' => 'test_many_swatches', + ]; + } + + /** + * Data provider for large swatches amount test. + * + * @return array + */ + public function getLargeSwatchesAmountAttributeData() : array + { + $maxInputVars = ini_get('max_input_vars'); + // Each option is at least 7 variables array for a visual swatch. + // Set options count to exceed max_input_vars by 20 options (140 variables). + $swatchVisualOptionsCount = (int)floor($maxInputVars / 7) + 20; + $swatchTextOptionsCount = (int)floor($maxInputVars / 4) + 80; + return [ + 'visual swatches' => $this->getSwatchVisualDataSet($swatchVisualOptionsCount), + 'text swatches' => $this->getSwatchTextDataSet($swatchTextOptionsCount) + ]; + } + + /** + * Test attribute saving with large amount of options exceeding maximum allowed by max_input_vars limit. + * @dataProvider getLargeSwatchesAmountAttributeData() + * @param array $attributeData + * @param int $expectedOptionsCount + * @param array $expectedLabels + * @return void + */ + public function testLargeOptionsDataSet( + array $attributeData, + int $expectedOptionsCount, + array $expectedLabels + ) : void { + $this->getRequest()->setPostValue($attributeData); + $this->dispatch('backend/catalog/product_attribute/save'); + $entityTypeId = $this->_objectManager->create( + \Magento\Eav\Model\Entity::class + )->setType( + \Magento\Catalog\Model\Product::ENTITY + )->getTypeId(); + + /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ + $attribute = $this->_objectManager->create( + \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class + )->setEntityTypeId( + $entityTypeId + ); + try { + $attribute->loadByCode($entityTypeId, 'test_many_swatches'); + $options = $attribute->getOptions(); + // assert that all options are saved without truncation + $this->assertEquals( + $expectedOptionsCount, + count($options), + 'Expected options count does not match (regarding first empty option for non-required attribute)' + ); + + foreach ($expectedLabels as $optionOrderNum => $label) { + $this->assertEquals( + $label, + $options[$optionOrderNum]->getLabel(), + "Label for option #{$optionOrderNum} does not match expected." + ); + } + } catch (LocalizedException $e) { + $this->fail('Test failed with exception on attribute model load: ' . $e); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Weee/Model/ResourceModel/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Weee/Model/ResourceModel/AttributeTest.php new file mode 100644 index 0000000000000..725a8f72c8d01 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Weee/Model/ResourceModel/AttributeTest.php @@ -0,0 +1,119 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Weee\Model\ResourceModel; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Eav\Model\Entity\Attribute as EavAttribute; +use Magento\Framework\EntityManager\MetadataPool; + +/** + * Test class for Magento\Catalog\Model\ResourceModel\Attribute class + * with backend model Magento\Weee\Model\Attribute\Backend\Weee\Tax. + * + * @see Magento\Catalog\Model\ResourceModel\Attribute + */ +class AttributeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Catalog\Model\ResourceModel\Attribute + */ + private $model; + + /** + * @var \Magento\Catalog\Model\ResourceModel\Product + */ + protected $productResource; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @var MetadataPool + */ + private $metadataPool; + + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + protected $objectManager; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->model = $this->objectManager->get( + \Magento\Catalog\Model\ResourceModel\Attribute::class + ); + $this->productResource = $this->objectManager->get( + \Magento\Catalog\Model\ResourceModel\Product::class + ); + $this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + $this->metadataPool = $this->objectManager->get(MetadataPool::class); + } + + /** + * Retrieve eav attribute row. + * + * @param int $entityTypeId + * @param int $attributeSetId + * @param int $attributeId + * @return array|false + */ + private function getEavEntityAttributeRow(int $entityTypeId, int $attributeSetId, int $attributeId) + { + $connection = $this->productResource->getConnection(); + $select = $connection->select() + ->from($this->productResource->getTable('eav_entity_attribute')) + ->where('attribute_set_id=?', $attributeSetId) + ->where('attribute_id=?', $attributeId) + ->where('entity_type_id=?', $entityTypeId); + + return $connection->fetchRow($select); + } + + /** + * Test to delete entity attribute with type "Fixed Product Tax". + * + * @magentoDataFixture Magento/Weee/_files/fixed_product_attribute.php + * @return void + */ + public function testDeleteEntityFixedTax() : void + { + /* @var EavAttribute $attribute */ + $attribute = $this->objectManager->get(EavAttribute::class); + $attribute->loadByCode(\Magento\Catalog\Model\Product::ENTITY, 'fixed_product_attribute'); + + $entityEavAttributeRow = $this->getEavEntityAttributeRow( + (int)$attribute->getEntityTypeId(), + 4, + (int)$attribute->getId() + ); + $this->assertNotEmpty( + $entityEavAttributeRow['entity_attribute_id'], + 'The record is absent in table `eav_entity_attribute` for `fixed_product_attribute`' + ); + + $attribute->setData('entity_attribute_id', $entityEavAttributeRow['entity_attribute_id']); + $this->model->deleteEntity($attribute); + + $entityEavAttributeRow = $this->getEavEntityAttributeRow( + (int)$attribute->getEntityTypeId(), + 4, + (int)$attribute->getId() + ); + $this->assertEmpty( + $entityEavAttributeRow, + 'The record was not removed from table `eav_entity_attribute` for `fixed_product_attribute`' + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php new file mode 100644 index 0000000000000..a20d1cac94228 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php @@ -0,0 +1,33 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */ +$attributeSet = $objectManager->create(\Magento\Eav\Model\Entity\Attribute\Set::class); + +$entityType = $objectManager->create(\Magento\Eav\Model\Entity\Type::class)->loadByCode('catalog_product'); +$defaultSetId = $objectManager->create(\Magento\Catalog\Model\Product::class)->getDefaultAttributeSetid(); + +$attributeGroupId = $attributeSet->getDefaultGroupId($entityType->getDefaultAttributeSetId()); + +$attributeData = [ + 'entity_type_id' => $entityType->getId(), + 'attribute_code' => 'fixed_product_attribute', + 'backend_model' => 'Magento\Weee\Model\Attribute\Backend\Weee\Tax', + 'is_required' => 0, + 'is_user_defined' => 1, + 'is_static' => 1, + 'attribute_set_id' => $defaultSetId, + 'attribute_group_id' => $attributeGroupId, +]; + +/** @var \Magento\Catalog\Model\Entity\Attribute $attribute */ +$attribute = $objectManager->create(\Magento\Eav\Model\Entity\Attribute::class); +$attribute->setData($attributeData); +$attribute->save(); diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute_rollback.php new file mode 100644 index 0000000000000..1d6e15b2e9a97 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute_rollback.php @@ -0,0 +1,14 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/* @var EavAttribute $attribute */ +$attribute = $objectManager->get(\Magento\Eav\Model\Entity\Attribute::class); +$attribute->loadByCode(\Magento\Catalog\Model\Product::ENTITY, 'fixed_product_attribute'); +$attribute->delete(); diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Rule/view/adminhtml/web/conditions-data-normalizer.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Rule/view/adminhtml/web/conditions-data-normalizer.test.js index 21c04d098ae6c..ec820e537789a 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Rule/view/adminhtml/web/conditions-data-normalizer.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Rule/view/adminhtml/web/conditions-data-normalizer.test.js @@ -65,5 +65,17 @@ define([ expect(normal.foo['1'].value).toEqual(123); expect(normal.foo['1--1']).toEqual(321); }); + + it('Check keys containing a dot are normalized', function () { + var normal = normalizer.normalize({ + 'foo[1][name.foo]': 'bar', + 'foo[1][value.foo]': 123, + 'foo[1--1]': 321 + }); + + expect(normal.foo['1']['name.foo']).toEqual('bar'); + expect(normal.foo['1']['value.foo']).toEqual(123); + expect(normal.foo['1--1']).toEqual(321); + }); }); }); diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/client.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/client.test.js index d3b5072a767bd..24dc535638514 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/client.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/client.test.js @@ -114,6 +114,7 @@ define([ $.ajax = jasmine.createSpy().and.callFake(function (req) { request = req.success; }); + jQueryMethods.notification = $.fn.notification; $.fn.notification = jasmine.createSpy(); obj.urls.beforeSave = 'requestPath'; obj.save(); diff --git a/dev/tests/js/jasmine/tests/lib/mage/backend/bootstrap.test.js b/dev/tests/js/jasmine/tests/lib/mage/backend/bootstrap.test.js index 396b62df0dfe9..60115c4ac2c64 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/backend/bootstrap.test.js +++ b/dev/tests/js/jasmine/tests/lib/mage/backend/bootstrap.test.js @@ -2,45 +2,35 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -/* global jQuery */ /* eslint-disable max-nested-callbacks */ define([ 'jquery', - 'squire', - 'mage/backend/notification' -], function ($, Squire) { + 'mage/backend/bootstrap' +], function ($) { 'use strict'; - var injector = new Squire(); - describe('mage/backend/bootstrap', function () { - beforeEach(function (done) { - injector.require(['mage/backend/bootstrap'], function () { - done(); - }); + var $pageMainActions; + + beforeEach(function () { + $pageMainActions = $('<div class="page-main-actions"></div>'); }); afterEach(function () { - try { - injector.clean(); - injector.remove(); - } catch (e) {} + $pageMainActions.remove(); }); describe('"sendPostponeRequest" method', function () { - it('should insert "Error" notification if request failed', function (done) { - jQuery('<div class="page-main-actions"></div>').appendTo('body'); - jQuery('body').notification(); + it('should insert "Error" notification if request failed', function () { + $pageMainActions.appendTo('body'); + $('body').notification(); - jQuery.ajax().abort(); + $.ajaxSettings.error(); - setTimeout(function () { - expect(jQuery('.message-error').length).toBe(1); - expect( - jQuery('body:contains("A technical problem with the server created an error")').length - ).toBe(1); - done(); - }, 1); + expect($('.message-error').length).toBe(1); + expect( + $('body:contains("A technical problem with the server created an error")').length + ).toBe(1); }); }); }); diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml index c57581d7f1621..5b8a4c8f37c99 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml @@ -30,7 +30,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="unique_null_key"> + <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -53,14 +53,15 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="some_unique_key"> + <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="some_foreign_key" column="tinyint" table="test_table" + <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="speedup_index" indexType="btree"> + <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema_whitelist.json b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema_whitelist.json index 14b4887b662e2..49866f645d09d 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema_whitelist.json +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema_whitelist.json @@ -23,7 +23,7 @@ "int_disabled_auto_increment": true }, "constraint": { - "unique_null_key": true + "AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE": true } }, "test_table": { @@ -46,11 +46,11 @@ "varbinary_rename": true }, "index": { - "speedup_index": true + "TEST_TABLE_TINYINT_BIGINT": true }, "constraint": { - "some_unique_key": true, - "some_foreign_key": true + "TEST_TABLE_SMALLINT_BIGINT": true, + "TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF": true } }, "store": { @@ -59,7 +59,7 @@ "store_owner": true }, "constraint": { - "STORE_OWNER_ID_REFERENCE": true + "STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID": true } }, "store_owner": { diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_modification.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_modification.php index a48a0a21b4f9b..a69e456ec4a8b 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_modification.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_modification.php @@ -7,7 +7,7 @@ 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(15) unsigned DEFAULT NULL, `int_disabled_auto_increment` smallint(12) unsigned DEFAULT \'0\', - UNIQUE KEY `unique_null_key` (`int_auto_increment_with_nullable`) + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'reference_table' => 'CREATE TABLE `reference_table` ( `tinyint_ref` tinyint(7) NOT NULL AUTO_INCREMENT, @@ -39,8 +39,9 @@ `mediumblob` mediumblob, `blob` blob, `boolean` tinyint(1) DEFAULT \'1\', - UNIQUE KEY `some_unique_key` (`smallint`,`bigint`), - KEY `speedup_index` (`tinyint`,`bigint`), - CONSTRAINT `some_foreign_key` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION + UNIQUE KEY `TEST_TABLE_SMALLINT_BIGINT` (`smallint`,`bigint`), + KEY `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`), + CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) +REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8', ]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_removal.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_removal.php index dea57d5d9a803..0091b89845a73 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_removal.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_removal.php @@ -6,7 +6,7 @@ return [ 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(12) unsigned NOT NULL AUTO_INCREMENT, - UNIQUE KEY `unique_null_key` (`int_auto_increment_with_nullable`) + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'reference_table' => 'CREATE TABLE `reference_table` ( `tinyint_ref` tinyint(7) NOT NULL AUTO_INCREMENT, @@ -37,8 +37,9 @@ `blob` blob, `boolean` tinyint(1) DEFAULT NULL, `varbinary_rename` varbinary(255) DEFAULT \'10101\', - UNIQUE KEY `some_unique_key` (`smallint`,`bigint`), - KEY `speedup_index` (`tinyint`,`bigint`), - CONSTRAINT `some_foreign_key` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION + UNIQUE KEY `TEST_TABLE_SMALLINT_BIGINT` (`smallint`,`bigint`), + KEY `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`), + CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) +REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8', ]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.php index 26ba8848095b3..01e007edb7684 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.php @@ -7,7 +7,7 @@ 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(12) unsigned NOT NULL AUTO_INCREMENT, `int_disabled_auto_increment` smallint(12) unsigned DEFAULT \'0\', - UNIQUE KEY `unique_null_key` (`int_auto_increment_with_nullable`) + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'reference_table' => 'CREATE TABLE `reference_table` ( `tinyint_ref` tinyint(7) NOT NULL AUTO_INCREMENT, @@ -23,7 +23,7 @@ `bigint_not_default_not_nullable` bigint(2) unsigned NOT NULL, `smallint_ref` smallint(254) NOT NULL DEFAULT \'0\', PRIMARY KEY (`tinyint_ref`,`smallint_ref`), - UNIQUE KEY `smallint_unique` (`smallint_ref`) + UNIQUE KEY `REFERENCE_TABLE_SMALLINT_REF` (`smallint_ref`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'test_table' => 'CREATE TABLE `test_table` ( `smallint` smallint(3) DEFAULT NULL, @@ -43,16 +43,16 @@ `boolean` tinyint(1) DEFAULT NULL, `integer_main` int(12) unsigned DEFAULT NULL, `smallint_main` smallint(254) NOT NULL DEFAULT \'0\', - UNIQUE KEY `some_unique_key` (`smallint`,`float`), - UNIQUE KEY `some_unique_key_2` (`double`), - KEY `some_foreign_key_new` (`smallint_main`), - KEY `some_foreign_key_without_action` (`integer_main`), - KEY `speedup_index_renamed` (`tinyint`,`bigint`), - CONSTRAINT `some_foreign_key` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) -ON DELETE SET NULL, - CONSTRAINT `some_foreign_key_new` FOREIGN KEY (`smallint_main`) REFERENCES `reference_table` (`smallint_ref`) -ON DELETE CASCADE, - CONSTRAINT `some_foreign_key_without_action` FOREIGN KEY (`integer_main`) REFERENCES `auto_increment_test` -(`int_auto_increment_with_nullable`) ON DELETE CASCADE + UNIQUE KEY `TEST_TABLE_SMALLINT_FLOAT` (`smallint`,`float`), + UNIQUE KEY `TEST_TABLE_DOUBLE` (`double`), + KEY `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`), + KEY `TEST_TABLE_SMALLINT_MAIN_REFERENCE_TABLE_SMALLINT_REF` (`smallint_main`), + KEY `FK_FB77604C299EB8612D01E4AF8D9931F2` (`integer_main`), + CONSTRAINT `FK_FB77604C299EB8612D01E4AF8D9931F2` FOREIGN KEY (`integer_main`) +REFERENCES `auto_increment_test` (`int_auto_increment_with_nullable`) ON DELETE CASCADE, + CONSTRAINT `TEST_TABLE_SMALLINT_MAIN_REFERENCE_TABLE_SMALLINT_REF` FOREIGN KEY (`smallint_main`) +REFERENCES `reference_table` (`smallint_ref`) ON DELETE CASCADE, + CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) +REFERENCES `reference_table` (`tinyint_ref`) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8', ]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/installation.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/installation.php index 82f945070443f..3e807c25e3519 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/installation.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/installation.php @@ -7,7 +7,7 @@ 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(12) unsigned NOT NULL AUTO_INCREMENT, `int_disabled_auto_increment` smallint(12) unsigned DEFAULT \'0\', - UNIQUE KEY `unique_null_key` (`int_auto_increment_with_nullable`) + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'reference_table' => 'CREATE TABLE `reference_table` ( `tinyint_ref` tinyint(7) NOT NULL AUTO_INCREMENT, @@ -39,8 +39,9 @@ `mediumblob` mediumblob, `blob` blob, `boolean` tinyint(1) DEFAULT NULL, - UNIQUE KEY `some_unique_key` (`smallint`,`bigint`), - KEY `speedup_index` (`tinyint`,`bigint`), - CONSTRAINT `some_foreign_key` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION + UNIQUE KEY `TEST_TABLE_SMALLINT_BIGINT` (`smallint`,`bigint`), + KEY `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`), + CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) +REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8', ]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.php index aa80af695cc99..f5b98ce8a2735 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.php @@ -10,8 +10,9 @@ 'before' => [ 'store' => 'CREATE TABLE `store` ( `store_owner_id` smallint(5) DEFAULT NULL COMMENT \'Store Owner Reference\', - KEY `STORE_OWNER_ID_REFERENCE` (`store_owner_id`), - CONSTRAINT `STORE_OWNER_ID_REFERENCE` FOREIGN KEY (`store_owner_id`) REFERENCES `store_owner` (`owner_id`) ON DELETE SET NULL + KEY `STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID` (`store_owner_id`), + CONSTRAINT `STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID` FOREIGN KEY (`store_owner_id`) +REFERENCES `store_owner` (`owner_id`) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'store_owner' => 'CREATE TABLE `store_owner` ( `owner_id` smallint(5) NOT NULL AUTO_INCREMENT, diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.php index 3b607574d167a..7bd0213c6590d 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.php @@ -7,6 +7,6 @@ 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(12) unsigned NOT NULL AUTO_INCREMENT, `int_disabled_auto_increment` smallint(12) unsigned DEFAULT \'0\', - UNIQUE KEY `unique_null_key` (`int_auto_increment_with_nullable`) + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8' ]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.php index 43680b4218f66..e642e57701149 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.php @@ -22,7 +22,7 @@ CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(12) UNSIGNED NOT NULL AUTO_INCREMENT , `int_disabled_auto_increment` smallint(12) UNSIGNED NULL DEFAULT 0 , -CONSTRAINT `unique_null_key` UNIQUE KEY (`int_auto_increment_with_nullable`) +CONSTRAINT `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` UNIQUE KEY (`int_auto_increment_with_nullable`) ) ENGINE=innodb DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci CREATE TABLE `test_table` ( @@ -41,9 +41,9 @@ `mediumblob` mediumblob NULL , `blob` blob NULL , `boolean` BOOLEAN NULL , -CONSTRAINT `some_unique_key` UNIQUE KEY (`smallint`,`bigint`), -CONSTRAINT `some_foreign_key` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION, -INDEX `speedup_index` (`tinyint`,`bigint`) +CONSTRAINT `TEST_TABLE_SMALLINT_BIGINT` UNIQUE KEY (`smallint`,`bigint`), +CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION, +INDEX `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`) ) ENGINE=innodb DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci CREATE TABLE `patch_list` ( diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php index e912d9fb96f47..76fcf6b2fad11 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php @@ -31,9 +31,9 @@ ], ], 'constraint' => [ - 'some_foreign_key' => [ + 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => [ 'type' => 'foreign', - 'name' => 'some_foreign_key', + 'name' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', 'column' => 'tinyint', 'table' => 'test_table', 'referenceTable' => 'reference_table', diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php index 7aaf37ba156f5..cd42a1e8fc360 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php @@ -120,12 +120,12 @@ ], ], 'constraint' => [ - 'unique_null_key' => [ + 'AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE' => [ 'column' => [ 'int_auto_increment_with_nullable' => 'int_auto_increment_with_nullable', ], 'type' => 'unique', - 'name' => 'unique_null_key', + 'name' => 'AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE', ], ], 'name' => 'auto_increment_test', @@ -225,17 +225,17 @@ ], ], 'constraint' => [ - 'some_unique_key' => [ + 'TEST_TABLE_SMALLINT_BIGINT' => [ 'column' => [ 'smallint' => 'smallint', 'bigint' => 'bigint', ], 'type' => 'unique', - 'name' => 'some_unique_key', + 'name' => 'TEST_TABLE_SMALLINT_BIGINT', ], - 'some_foreign_key' => [ + 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => [ 'type' => 'foreign', - 'name' => 'some_foreign_key', + 'name' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', 'column' => 'tinyint', 'table' => 'test_table', 'referenceTable' => 'reference_table', @@ -244,12 +244,12 @@ ], ], 'index' => [ - 'speedup_index' => [ + 'TEST_TABLE_TINYINT_BIGINT' => [ 'column' => [ 'tinyint' => 'tinyint', 'bigint' => 'bigint', ], - 'name' => 'speedup_index', + 'name' => 'TEST_TABLE_TINYINT_BIGINT', 'indexType' => 'btree', ], ], diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/InstallSchema.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/InstallSchema.php new file mode 100644 index 0000000000000..22cfcd1fa2870 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/InstallSchema.php @@ -0,0 +1,126 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\TestSetupDeclarationModule1\Setup; + +use Magento\Framework\Setup\InstallSchemaInterface; +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\SchemaSetupInterface; + +/** + * @codeCoverageIgnore + */ +class InstallSchema implements InstallSchemaInterface +{ + /** + * {@inheritdoc} + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) + { + $installer = $setup; + + $installer->startSetup(); + + //Create first table + $table = $installer->getConnection() + ->newTable($installer->getTable('reference_table')) + ->addColumn( + 'smallint_ref', + \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, + 3, + ['primary' => true, 'identity' => true, 'nullable' => false], + 'Smallint' + ) + ->setComment('Reference table'); + $installer->getConnection()->createTable($table); + + $testTable = $installer->getConnection()->newTable($installer->getTable('test_table')) + ->addColumn( + 'smallint', + \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, + 2, + ['nullable' => true, 'default' => 0], + 'Smallint' + ) + ->addColumn( + 'bigint', + \Magento\Framework\DB\Ddl\Table::TYPE_BIGINT, + 10, + ['nullable' => true, 'unsigned' => false, 'default' => 0], + 'Bigint' + ) + ->addColumn( + 'float', + \Magento\Framework\DB\Ddl\Table::TYPE_FLOAT, + null, + ['default' => 0], + 'Float' + ) + ->addColumn( + 'date', + \Magento\Framework\DB\Ddl\Table::TYPE_DATE, + null, + [], + 'Date' + ) + ->addColumn( + 'timestamp', + \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, + null, + ['default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT_UPDATE], + 'Timestamp' + ) + ->addColumn( + 'mediumtext', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 11222222, + [], + 'Mediumtext' + ) + ->addColumn( + 'varchar', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 254, + ['nullable' => true], + 'Varchar' + ) + ->addColumn( + 'boolean', + \Magento\Framework\DB\Ddl\Table::TYPE_BOOLEAN, + 1, + [], + 'Boolean' + ) + ->addIndex( + $installer->getIdxName('test_table', ['smallint', 'bigint']), + ['smallint', 'bigint'], + ['type' => \Magento\Framework\DB\Adapter\Pdo\Mysql::INDEX_TYPE_UNIQUE] + ) + ->addIndex( + $installer->getIdxName('test_table', ['bigint']), + ['bigint'] + ) + ->addForeignKey( + $installer->getFkName( + $installer->getTable('test_table'), + 'smallint', + 'reference_table', + 'smallint_ref' + ), + 'smallint', + $installer->getTable('reference_table'), + 'smallint_ref', + \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE + ) + ->setComment('Test Table'); + $installer->getConnection()->createTable($testTable); + + $installer->endSetup(); + } +} diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml new file mode 100644 index 0000000000000..7384c4ed7baab --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="reference_table" resource="default" comment="Reference table"> + <column xsi:type="smallint" name="smallint_ref" padding="6" nullable="false" unsigned="false" identity="true" comment="Smallint"/> + <constraint xsi:type="primary" name="tinyint_primary"> + <column name="smallint_ref"/> + </constraint> + </table> + <table name="test_table" resource="default" comment="Test Table"> + <column xsi:type="smallint" name="smallint" default="0" padding="6" nullable="true" unsigned="false" comment="Smallint"/> + <column xsi:type="bigint" name="bigint" default="0" padding="20" nullable="true" unsigned="false" comment="Bigint"/> + <column xsi:type="float" name="float" default="0" scale="0" precision="10" comment="Float"/> + <column xsi:type="date" name="date" comment="Date"/> + <column xsi:type="timestamp" name="timestamp" default="CURRENT_TIMESTAMP" on_update="true" comment="Timestamp"/> + <column xsi:type="mediumtext" name="mediumtext" comment="Mediumtext"/> + <column xsi:type="varchar" name="varchar" length="254" nullable="true" comment="Varchar"/> + <column xsi:type="boolean" name="boolean" comment="Boolean"/> + <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <column name="smallint"/> + <column name="bigint"/> + </constraint> + <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + column="smallint" table="test_table" + referenceTable="reference_table" referenceColumn="smallint_ref" onDelete="CASCADE"/> + <index name="TEST_TABLE_BIGINT" indexType="btree"> + <column name="bigint"/> + </index> + </table> +</schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml index 242b555a14949..4d3d51b9c0237 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml @@ -10,7 +10,7 @@ <table name="store"> <column name="store_owner_id" xsi:type="smallint" nullable="true" comment="Store Owner Reference" /> <constraint xsi:type="foreign" - name="STORE_OWNER_ID_REFERENCE" + name="STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID" column="store_owner_id" table="store" referenceTable="store_owner" @@ -20,7 +20,7 @@ <table name="store_owner" comment="Store owner information" engine="innodb" resource="default"> <column name="owner_id" xsi:type="smallint" nullable="false" unsigned="false" identity="true" /> <column name="store_owner_name" onCreate="migrateDataFrom(label)" xsi:type="varchar" length="255" comment="Store Owner Name" /> - <constraint xsi:type="primary"> + <constraint xsi:type="primary" name="PRIMARY"> <column name="owner_id" /> </constraint> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml index a748af135c209..0adcd5c52f962 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml @@ -29,7 +29,7 @@ <column xsi:type="int" name="int_auto_increment_with_nullable" padding="15" unsigned="true" nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="unique_null_key"> + <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -52,14 +52,15 @@ <column xsi:type="boolean" name="boolean" default="true"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="some_unique_key"> + <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="some_foreign_key" column="tinyint" table="test_table" + <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="speedup_index" indexType="btree"> + <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml index e7361dd28fc0a..4b78f436eab37 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml @@ -27,7 +27,7 @@ <table name="auto_increment_test" resource="default"> <column xsi:type="int" name="int_auto_increment_with_nullable" identity="true" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="unique_null_key"> + <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -50,14 +50,15 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="false"/> <!--Constraints--> - <constraint xsi:type="unique" name="some_unique_key"> + <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="some_foreign_key" column="tinyint" table="test_table" + <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="speedup_index" indexType="btree"> + <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema_whitelist.json b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema_whitelist.json index 890fea33106b7..9105a2b0b25cb 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema_whitelist.json +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema_whitelist.json @@ -23,7 +23,7 @@ "int_disabled_auto_increment": true }, "constraint": { - "unique_null_key": true + "AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE": true } }, "test_table": { @@ -46,11 +46,11 @@ "varbinary_rename": true }, "index": { - "speedup_index": true + "TEST_TABLE_TINYINT_BIGINT": true }, "constraint": { - "some_unique_key": true, - "some_foreign_key": true + "TEST_TABLE_SMALLINT_BIGINT": true, + "TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF": true } } } diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml index 97f1862e14028..68f2810e8eed7 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml @@ -26,7 +26,7 @@ <column name="tinyint_ref"/> <column name="smallint_ref"/> </constraint> - <constraint xsi:type="unique" name="smallint_unique"> + <constraint xsi:type="unique" name="REFERENCE_TABLE_SMALLINT_REF"> <column name="smallint_ref"/> </constraint> </table> @@ -35,7 +35,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="unique_null_key"> + <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -60,21 +60,23 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="some_unique_key"> + <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_FLOAT"> <column name="smallint"/> <column name="float"/> </constraint> - <constraint xsi:type="unique" name="some_unique_key_2"> + <constraint xsi:type="unique" name="TEST_TABLE_DOUBLE"> <column name="double"/> </constraint> <constraint xsi:type="foreign" name="some_foreign_key_new" column="smallint_main" table="test_table" referenceTable="reference_table" referenceColumn="smallint_ref" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="some_foreign_key" column="tinyint" table="test_table" + <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="some_foreign_key_without_action" column="integer_main" table="test_table" + <constraint xsi:type="foreign" name="FK_FB77604C299EB8612D01E4AF8D9931F2" + column="integer_main" table="test_table" referenceTable="auto_increment_test" referenceColumn="int_auto_increment_with_nullable"/> <!--Indexes--> - <index name="speedup_index_renamed" indexType="btree"> + <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema_whitelist.json b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema_whitelist.json index bcae522f68995..16ff756ef552a 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema_whitelist.json +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema_whitelist.json @@ -23,7 +23,7 @@ "int_disabled_auto_increment": true }, "constraint": { - "unique_null_key": true + "AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE": true } }, "test_table": { @@ -46,11 +46,11 @@ "varbinary_rename": true }, "index": { - "speedup_index": true + "TEST_TABLE_TINYINT_BIGINT": true }, "constraint": { - "some_unique_key": true, - "some_foreign_key": true + "TEST_TABLE_SMALLINT_BIGINT": true, + "TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF": true } } } diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml index 57403cbea3fdc..0a0131e500641 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml @@ -12,7 +12,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="unique_null_key"> + <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml index 2b8b162bf2a9e..e4a5ca05d02fe 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml @@ -12,7 +12,8 @@ </table> <table name="test_table" resource="default"> <column xsi:type="tinyint" name="tinyint" default="0" padding="7" nullable="true" unsigned="false"/> - <constraint xsi:type="foreign" name="some_foreign_key" column="tinyint" table="test_table" + <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref"/> </table> </schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/InstallSchema.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/InstallSchema.php index 3b73610f18270..8678218a51e05 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/InstallSchema.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/InstallSchema.php @@ -97,16 +97,21 @@ public function install(SchemaSetupInterface $setup, ModuleContextInterface $con 'Boolean' ) ->addIndex( - 'some_unique_key', + $installer->getIdxName($installer->getTable('test_table'), ['smallint', 'bigint']), ['smallint', 'bigint'], ['type' => \Magento\Framework\DB\Adapter\Pdo\Mysql::INDEX_TYPE_UNIQUE] ) ->addIndex( - 'speedup_index', + $installer->getIdxName($installer->getTable('test_table'), ['bigint']), ['bigint'] ) ->addForeignKey( - 'some_foreign_key', + $installer->getFkName( + $installer->getTable('test_table'), + 'smallint', + $installer->getTable('reference_table'), + 'smallint_ref' + ), 'smallint', $installer->getTable('reference_table'), 'smallint_ref', diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml index 97b375d228e0c..6b92440ca92f5 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml @@ -22,13 +22,14 @@ <column xsi:type="mediumtext" name="mediumtext" comment="Mediumtext"/> <column xsi:type="varchar" name="varchar" length="254" nullable="true" comment="Varchar"/> <column xsi:type="boolean" name="boolean" comment="Boolean"/> - <constraint xsi:type="unique" name="some_unique_key"> + <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="some_foreign_key" column="smallint" table="test_table" + <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + column="smallint" table="test_table" referenceTable="reference_table" referenceColumn="smallint_ref" onDelete="CASCADE"/> - <index name="speedup_index" indexType="btree"> + <index name="TEST_TABLE_BIGINT" indexType="btree"> <column name="bigint"/> </index> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml index 00b5d6f9bb27d..b6ff634e6ef1d 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml @@ -21,7 +21,8 @@ <column xsi:type="tinyint" name="tinyint" padding="7" nullable="true" unsigned="false"/> <column xsi:type="varchar" name="varchar" length="254" nullable="true"/> <column xsi:type="varbinary" name="varbinary" default="10101" /> - <constraint xsi:type="foreign" name="some_foreign_key" column="tinyint" table="test_table" + <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="CASCADE"/> <constraint xsi:type="primary" name="PRIMARY"> <column name="smallint" /> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml index 00b5d6f9bb27d..b6ff634e6ef1d 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml @@ -21,7 +21,8 @@ <column xsi:type="tinyint" name="tinyint" padding="7" nullable="true" unsigned="false"/> <column xsi:type="varchar" name="varchar" length="254" nullable="true"/> <column xsi:type="varbinary" name="varbinary" default="10101" /> - <constraint xsi:type="foreign" name="some_foreign_key" column="tinyint" table="test_table" + <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="CASCADE"/> <constraint xsi:type="primary" name="PRIMARY"> <column name="smallint" /> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml index 3eeb141c2e606..9263004c6e7f6 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml @@ -30,7 +30,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="unique_null_key"> + <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -53,14 +53,15 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="some_unique_key"> + <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="some_foreign_key" column="tinyint" table="test_table" + <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="speedup_index" indexType="btree"> + <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema_whitelist.json b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema_whitelist.json index 890fea33106b7..9105a2b0b25cb 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema_whitelist.json +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema_whitelist.json @@ -23,7 +23,7 @@ "int_disabled_auto_increment": true }, "constraint": { - "unique_null_key": true + "AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE": true } }, "test_table": { @@ -46,11 +46,11 @@ "varbinary_rename": true }, "index": { - "speedup_index": true + "TEST_TABLE_TINYINT_BIGINT": true }, "constraint": { - "some_unique_key": true, - "some_foreign_key": true + "TEST_TABLE_SMALLINT_BIGINT": true, + "TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF": true } } } diff --git a/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/ReinstallInstance.php b/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/ReinstallInstance.php index 6f7949861928e..e3825db2bd1f1 100644 --- a/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/ReinstallInstance.php +++ b/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/ReinstallInstance.php @@ -33,12 +33,12 @@ public function __construct(\Magento\TestFramework\Application $application) public function startTest() { - $this->application->reinitialize(); /** @var ObjectManager $objectManager */ $objectManager = Bootstrap::getObjectManager(); $resourceConnection = $objectManager->create(ResourceConnection::class); $objectManager->removeSharedInstance(ResourceConnection::class); $objectManager->addSharedInstance($resourceConnection, ResourceConnection::class); + $this->application->reinitialize(); } /** diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/BCMultiModuleTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/BCMultiModuleTest.php index 6ea79f9628e39..f40339fd02439 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/BCMultiModuleTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/BCMultiModuleTest.php @@ -7,14 +7,12 @@ namespace Magento\Setup; use Magento\Framework\Module\DbVersionInfo; -use Magento\Framework\Module\ModuleList; use Magento\Framework\Module\ModuleResource; use Magento\Framework\Setup\Declaration\Schema\Db\DbSchemaReaderInterface; use Magento\TestFramework\Deploy\CliCommand; use Magento\TestFramework\Deploy\TableData; use Magento\TestFramework\Deploy\TestModuleManager; use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\SetupTestCase; /** @@ -77,7 +75,7 @@ public function testFirstCleanInstall() //Check if declaration is applied $indexes = $this->dbSchemaReader->readIndexes('test_table', 'default'); self::assertCount(1, $indexes); - self::assertArrayHasKey('speedup_index', $indexes); + self::assertArrayHasKey('TEST_TABLE_TINYINT_BIGINT', $indexes); //Check UpgradeSchema old format, that modify declaration $columns = $this->dbSchemaReader->readColumns('test_table', 'default'); $floatColumn = $columns['float']; @@ -199,4 +197,69 @@ public function testDSFirstRelease() $tables = $this->dbSchemaReader->readTables('default'); self::assertNotContains('custom_table', $tables); } + + /** + * @moduleName Magento_TestSetupDeclarationModule1 + * @dataProvider firstCleanInstallOneModuleDataProvider + * @param string $dbPrefix + * @param string $tableName + * @param string $indexName + * @param string $constraintName + * @param string $foreignKeyName + * @throws \Exception + */ + public function testFirstCleanInstallOneModule( + string $dbPrefix, + string $tableName, + string $indexName, + string $constraintName, + string $foreignKeyName + ) { + $this->cliCommand->install( + [ + 'Magento_TestSetupDeclarationModule1' + ], + [ + 'db-prefix' => $dbPrefix, + ] + ); + + $indexes = $this->dbSchemaReader + ->readIndexes($tableName, 'default'); + self::assertCount(1, $indexes); + self::assertArrayHasKey($indexName, $indexes); + + $constraints = $this->dbSchemaReader + ->readConstraints($tableName, 'default'); + self::assertCount(1, $constraints); + self::assertArrayHasKey($constraintName, $constraints); + + $foreignKeys = $this->dbSchemaReader + ->readReferences($tableName, 'default'); + self::assertCount(1, $foreignKeys); + self::assertArrayHasKey($foreignKeyName, $foreignKeys); + } + + /** + * @return array + */ + public function firstCleanInstallOneModuleDataProvider() + { + return [ + 'Installation without db prefix' => [ + 'dbPrefix' => '', + 'tableName' => 'test_table', + 'indexName' => 'TEST_TABLE_TINYINT_BIGINT', + 'constraintName' => 'TEST_TABLE_SMALLINT_BIGINT', + 'foreignKeyName' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', + ], + 'Installation with db prefix' => [ + 'dbPrefix' => 'spec_', + 'tableName' => 'spec_test_table', + 'indexName' => 'SPEC_TEST_TABLE_TINYINT_BIGINT', + 'constraintName' => 'SPEC_TEST_TABLE_SMALLINT_BIGINT', + 'foreignKeyName' => 'SPEC_TEST_TABLE_TINYINT_SPEC_REFERENCE_TABLE_TINYINT_REF', + ] + ]; + } } diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php index 2bdf85bc95217..34d432e566fec 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php @@ -80,7 +80,7 @@ public function testInstallation() //Second time installation should not find anything as we do not change anything self::assertNull($diff->getAll()); $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getData(), $shardData); + self::assertEquals($this->getTrimmedData(), $shardData); } /** @@ -111,7 +111,7 @@ public function testInstallationWithColumnsModification() ); self::assertNull($diff->getAll()); $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getData(), $shardData); + self::assertEquals($this->getTrimmedData(), $shardData); } /** @@ -157,7 +157,7 @@ public function testInstallationWithColumnsRemoval() ); self::assertNull($diff->getAll()); $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getData(), $shardData); + self::assertEquals($this->getTrimmedData(), $shardData); } /** @@ -243,7 +243,7 @@ public function testInstallWithCodeBaseRollback() ['Magento_TestSetupDeclarationModule1'] ); $beforeRollback = $this->describeTable->describeShard('default'); - self::assertEquals($this->getData()['before'], $beforeRollback); + self::assertEquals($this->getTrimmedData()['before'], $beforeRollback); //Move db_schema.xml file and tried to install $this->moduleManager->updateRevision( 'Magento_TestSetupDeclarationModule1', diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeSchemaBuilderTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeSchemaBuilderTest.php index 07544c25c45e4..d4126d9d1e16c 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeSchemaBuilderTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeSchemaBuilderTest.php @@ -79,7 +79,7 @@ public function testSchemaBuilder() /** * @var Reference $foreignKey */ - $foreignKey = $testTable->getConstraintByName('some_foreign_key'); + $foreignKey = $testTable->getConstraintByName('TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF'); self::assertEquals('NO ACTION', $foreignKey->getOnDelete()); self::assertEquals('tinyint_ref', $foreignKey->getReferenceColumn()->getName()); } diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DiffOldSchemaTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DiffOldSchemaTest.php index 3fb117896eaa9..0521a832ae392 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DiffOldSchemaTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DiffOldSchemaTest.php @@ -96,6 +96,58 @@ public function testOldDiff() ); } + /** + * @moduleName Magento_TestSetupDeclarationModule1 + * @param string $dbPrefix + * @throws \Exception + * @dataProvider oldSchemaUpgradeDataProvider + */ + public function testOldSchemaUpgrade(string $dbPrefix) + { + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule1', + 'old_diff_before', + 'db_schema.xml', + 'etc' + ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule1', + 'base_update', + 'InstallSchema.php', + 'Setup' + ); + $this->cliCommad->install( + ['Magento_TestSetupDeclarationModule1'], + ['db-prefix' => $dbPrefix] + ); + //Move db_schema.xml + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule1', + 'base_update', + 'db_schema.xml', + 'etc' + ); + $declarativeSchema = $this->schemaConfig->getDeclarationConfig(); + $generatedSchema = $this->schemaConfig->getDbConfig(); + $diff = $this->schemaDiff->diff($declarativeSchema, $generatedSchema); + self::assertEmpty($diff->getAll()); + } + + /** + * @return array + */ + public function oldSchemaUpgradeDataProvider(): array + { + return [ + 'Without db prefix' => [ + 'dbPrefix' => '', + ], + 'With db prefix' => [ + 'dbPrefix' => 'spec_', + ], + ]; + } + /** * @return array */ diff --git a/dev/tests/static/framework/Magento/TestFramework/Utility/ChangedFiles.php b/dev/tests/static/framework/Magento/TestFramework/Utility/ChangedFiles.php index 6470bc0c22086..3d7f5f2604d7a 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Utility/ChangedFiles.php +++ b/dev/tests/static/framework/Magento/TestFramework/Utility/ChangedFiles.php @@ -32,7 +32,7 @@ public static function getPhpFiles($changedFilesList, $fileTypes = 0) $fileUtilities = Files::init(); if (isset($_ENV['INCREMENTAL_BUILD'])) { $phpFiles = []; - foreach (glob($changedFilesList) as $listFile) { + foreach (glob($changedFilesList, GLOB_NOSORT) as $listFile) { $phpFiles = array_merge($phpFiles, file($listFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)); } array_walk( diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/HhvmCompatibilityTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/HhvmCompatibilityTest.php index e33b771b3c645..c552e0daa97df 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/HhvmCompatibilityTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/HhvmCompatibilityTest.php @@ -47,6 +47,24 @@ class HhvmCompatibilityTest extends \PHPUnit\Framework\TestCase 'serialize_precision', ]; + /** + * Whitelist of variables allowed in files. + * + * @var array + */ + private $whitelistVarsInFiles = [ + 'max_input_vars' => [ + 'integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php', + 'integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php', + ] + ]; + + /** + * Test allowed directives. + * + * @SuppressWarnings(PHPMD.NPathComplexity) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ public function testAllowedIniGetSetDirectives() { $deniedDirectives = []; @@ -55,7 +73,19 @@ public function testAllowedIniGetSetDirectives() if ($fileDirectives) { $fileDeniedDirectives = array_diff($fileDirectives, $this->allowedDirectives); if ($fileDeniedDirectives) { - $deniedDirectives[$file] = array_unique($fileDeniedDirectives); + $deniedDirectivesInFile = array_unique($fileDeniedDirectives); + foreach ($deniedDirectivesInFile as $key => $deniedDirective) { + if (isset($this->whitelistVarsInFiles[$deniedDirective])) { + foreach ($this->whitelistVarsInFiles[$deniedDirective] as $whitelistFile) { + if (strpos($file, $whitelistFile) !== false) { + unset($deniedDirectivesInFile[$key]); + } + } + } + } + if ($deniedDirectivesInFile) { + $deniedDirectives[$file] = $deniedDirectivesInFile; + } } } } diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php index 8048925a4e542..5877ee5cbcc48 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Xml/SchemaTest.php @@ -106,7 +106,9 @@ private function _filterSpecialCases(&$files) '#etc/countries.xml$#', '#conf/schema.xml$#', '#layout/swagger_index_index.xml$#', - '#Doc/etc/doc/vars.xml$#' + '#Doc/etc/doc/vars.xml$#', + '#phpunit.xml$#', + '#etc/db_schema.xml$#' ]; foreach ($list as $pattern) { foreach ($files as $key => $value) { diff --git a/dev/tools/UpgradeScripts/pre_composer_update_2.3.php b/dev/tools/UpgradeScripts/pre_composer_update_2.3.php new file mode 100644 index 0000000000000..6fe629e717b93 --- /dev/null +++ b/dev/tools/UpgradeScripts/pre_composer_update_2.3.php @@ -0,0 +1,414 @@ +#!/usr/bin/php +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +$_scriptName = basename(__FILE__); + +define( + 'SYNOPSIS', +<<<SYNOPSIS +Updates Magento with 2.3 requirements that can't be done by `composer update` or `bin/magento setup:upgrade`. +Run this script after upgrading to PHP 7.1/7.2 and before running `composer update` or `bin/magento setup:upgrade`. + +Steps included: + - Require new version of the metapackage + - Update "require-dev" section + - Add "Zend\\Mvc\\Controller\\": "setup/src/Zend/Mvc/Controller/" to composer.json "autoload":"psr-4" section + - Update Magento/Updater if it's installed + - Update name, version, and description fields in the root composer.json + +Usage: php -f $_scriptName -- --root='</path/to/magento/root/>' [--composer='</path/to/composer/executable>'] + [--edition='<community|enterprise>'] [--repo='<composer_repo_url>'] [--version='<version_constraint>'] + [--help] + +Required: + --root='</path/to/magento/root/>' + Path to the Magento installation root directory + +Optional: + --composer='</path/to/composer/executable>' + Path to the composer executable + - Default: The composer found in the system PATH + + --edition='<community|enterprise>' + Target Magento edition for the update. Open Source = 'community', Commerce = 'enterprise' + - Default: The edition currently required in composer.json + + --repo='<composer_repo_url>' + The Magento repository url to use to pull the new packages + - Default: The Magento repository configured in composer.json + + --version='<version_constraint>' + A composer version constraint for allowable 2.3 packages. Versions other than 2.3 are not handled by this script + See https://getcomposer.org/doc/articles/versions.md#writing-version-constraints for more information. + - Default: The latest 2.3 version available in the Magento repository + + --help + Display this message +SYNOPSIS +); + +$opts = getopt('', [ + 'root:', + 'composer:', + 'edition:', + 'repo:', + 'version:', + 'help' +]); + +// Log levels available for use with output() function +define('INFO', 0); +define('WARN', 1); +define('ERROR', 2); + +if (isset($opts['help'])) { + output(SYNOPSIS); + exit(0); +} + +try { + if (version_compare(PHP_VERSION, '7.1', '<') || version_compare(PHP_VERSION, '7.3', '>=')) { + preg_match('/^\d+\.\d+\.\d+/',PHP_VERSION, $matches); + $phpVersion = $matches[0]; + throw new Exception("Invalid PHP version '$phpVersion'. Magento 2.3 requires PHP 7.1 or 7.2"); + } + + /**** Populate and Validate Settings ****/ + + if (empty($opts['root']) || !is_dir($opts['root'])) { + throw new BadMethodCallException('Existing Magento root directory must be supplied with --root'); + } + $rootDir = $opts['root']; + + $composerFile = "$rootDir/composer.json"; + if (!file_exists($composerFile)) { + throw new InvalidArgumentException("Supplied Magento root directory '$rootDir' does not contain composer.json"); + } + + $composerData = json_decode(file_get_contents($composerFile), true); + + $metapackageMatcher = '/^magento\/product\-(?<edition>community|enterprise)\-edition$/'; + foreach (array_keys($composerData['require']) as $requiredPackage) { + if (preg_match($metapackageMatcher, $requiredPackage, $matches)) { + $edition = $matches['edition']; + break; + } + } + if (empty($edition)) { + throw new InvalidArgumentException("No Magento metapackage found in $composerFile"); + } + + // Override composer.json edition if one is passed to the script + if (!empty($opts['edition'])) { + $edition = $opts['edition']; + } + $edition = strtolower($edition); + + if ($edition !== 'community' && $edition !== 'enterprise') { + throw new InvalidArgumentException("Only 'community' and 'enterprise' editions allowed; '$edition' given"); + } + + $composerExec = (!empty($opts['composer']) ? $opts['composer'] : 'composer'); + if (basename($composerExec, '.phar') != 'composer') { + throw new InvalidArgumentException("'$composerExec' is not a composer executable"); + } + + // Use 'command -v' to check if composer is executable + exec("command -v $composerExec", $out, $composerFailed); + if ($composerFailed) { + if ($composerExec == 'composer') { + $message = 'Composer executable is not available in the system PATH'; + } + else { + $message = "Invalid composer executable '$composerExec'"; + } + throw new InvalidArgumentException($message); + } + + // The composer command uses the Magento root as the working directory so this script can be run from anywhere + $composerExec = "$composerExec --working-dir='$rootDir'"; + + // Set the version constraint to any 2.3 package if not specified + $constraint = !empty($opts['version']) ? $opts['version'] : '2.3.*'; + + // Composer package names + $project = "magento/project-$edition-edition"; + $metapackage = "magento/product-$edition-edition"; + + // Get the list of potential Magento repositories to search for the update package + $mageUrls = []; + $authFailed = []; + if (!empty($opts['repo'])) { + $mageUrls[] = $opts['repo']; + } + else { + foreach ($composerData['repositories'] as $label => $repo) { + if (strpos(strtolower($label), 'mage') !== false || strpos($repo['url'], '.mage') !== false) { + $mageUrls[] = $repo['url']; + } + } + + if (count($mageUrls) == 0) { + throw new InvalidArgumentException('No Magento repository urls found in composer.json'); + } + } + + $tempDir = findUnusedFilename($rootDir, 'temp_project'); + $projectConstraint = "$project='$constraint'"; + $version = null; + $description = null; + + output("**** Searching for a matching version of $project ****"); + + // Try to retrieve a 2.3 package from each Magento repository until one is found + foreach ($mageUrls as $repoUrl) { + try { + output("\\nChecking $repoUrl"); + deleteFilepath($tempDir); + runComposer("create-project --repository=$repoUrl $projectConstraint $tempDir --no-install"); + + // Make sure the downloaded package is 2.3 + $newComposer = json_decode(file_get_contents("$tempDir/composer.json"), true); + $version = $newComposer['version']; + $description = $newComposer['description']; + + if (strpos($version, '2.3.') !== 0) { + throw new InvalidArgumentException("Bad 2.3 version constraint '$constraint'; version $version found"); + } + + // If no errors occurred, set this as the correct repo, forget errors from previous repos, and move forward + output("\\n**** Found compatible $project version: $version ****"); + $repo = $repoUrl; + unset($exception); + break; + } + catch (Exception $e) { + // If this repository doesn't have a valid package, save the error but continue checking any others + output("Failed to find a valid 2.3 $project package on $repoUrl", WARN); + $exception = $e; + } + } + + // If a valid project package hasn't been found, throw the last error + if (isset($exception)) { + throw $exception; + } + + output("\\n**** Executing Updates ****"); + + $composerBackup = findUnusedFilename($rootDir, 'composer.json.bak'); + output("\\nBacking up $composerFile to $composerBackup"); + copy($composerFile, $composerBackup); + + // Add the repository to composer.json if needed without overwriting any existing ones + $repoUrls = array_map(function ($r) { return $r['url']; }, $composerData['repositories']); + if (!in_array($repo, $repoUrls)) { + $repoLabels = array_map('strtolower',array_keys($composerData['repositories'])); + $newLabel = 'magento'; + if (in_array($newLabel, $repoLabels)) { + $count = count($repoLabels); + for ($i = 1; $i <= $count; $i++) { + if (!in_array("$newLabel-$i", $repoLabels)) { + $newLabel = "$newLabel-$i"; + break; + } + } + } + output("\\nAdding $repo to composer repositories under label '$newLabel'"); + runComposer("config repositories.$newLabel composer $repo"); + } + + output("\\nUpdating Magento metapackage requirement to $metapackage=$version"); + if ($edition == 'enterprise') { + // Community -> Enterprise upgrades need to remove the community edition metapackage + runComposer('remove magento/product-community-edition --no-update'); + output(''); + } + runComposer("require $metapackage=$version --no-update"); + + output('\nUpdating "require-dev" section of composer.json'); + runComposer('require --dev ' . + 'phpunit/phpunit:~6.2.0 ' . + 'friendsofphp/php-cs-fixer:~2.10.1 ' . + 'lusitanian/oauth:~0.8.10 ' . + 'pdepend/pdepend:2.5.2 ' . + 'sebastian/phpcpd:~3.0.0 ' . + 'squizlabs/php_codesniffer:3.2.2 --no-update'); + output(''); + runComposer('remove --dev sjparkinson/static-review fabpot/php-cs-fixer --no-update'); + + output('\nAdding "Zend\\\\Mvc\\\\Controller\\\\": "setup/src/Zend/Mvc/Controller/" to "autoload": "psr-4"'); + $composerData['autoload']['psr-4']['Zend\\Mvc\\Controller\\'] = 'setup/src/Zend/Mvc/Controller/'; + + if (preg_match('/^magento\/project\-(community|enterprise)\-edition$/', $composerData['name'])) { + output('\nUpdating project name, version, and description'); + $composerData['name'] = $project; + $composerData['version'] = $version; + $composerData['description'] = $description; + } + + file_put_contents($composerFile, json_encode($composerData, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT)); + + // Update Magento/Updater if it's installed + $updateDir = "$rootDir/update"; + if (file_exists($updateDir)) { + $updateBackup = findUnusedFilename($rootDir, 'update.bak'); + output("\\nBacking up Magento/Updater directory $updateDir to $updateBackup"); + rename($updateDir, $updateBackup); + output('\nUpdating Magento/Updater'); + rename("$tempDir/update", $updateDir); + } + + // Remove temp project directory that was used for repo/version validation and new source for Magento/Updater + deleteFilepath($tempDir); + + output("\\n**** Script Complete! $composerFile updated to Magento version $version ****"); + if (count($authFailed) > 0) { + output('Repository authentication failures occurred!', WARN); + output(' * Failed authentication could result in incorrect package versions', WARN); + output(' * To resolve, add credentials for the repositories to auth.json', WARN); + output(' * URL(s) failing authentication: ' . join(', ', array_keys($authFailed)), WARN); + } +} catch (Exception $e) { + if ($e->getPrevious()) { + $e = $e->getPrevious(); + } + + try { + output($e->getMessage(), ERROR, get_class($e)); + output('Script failed! See usage information with --help', ERROR); + + if (isset($composerBackup) && file_exists($composerBackup)) { + output("Resetting $composerFile backup"); + deleteFilepath($composerFile); + rename($composerBackup, $composerFile); + } + if (isset($updateBackup) && file_exists($updateBackup)) { + output("Resetting $updateDir backup"); + deleteFilepath($updateDir); + rename($updateBackup, $updateDir); + } + if (isset($tempDir) && file_exists($tempDir)) { + output('Removing temporary project directory'); + deleteFilepath($tempDir); + } + } + catch (Exception $e2) { + output($e2->getMessage(), ERROR, get_class($e2)); + output('Backup restoration or directory cleanup failed', ERROR); + } + + exit($e->getCode() == 0 ? 1 : $e->getCode()); +} + +/** + * Gets a variant of a filename that doesn't already exist so we don't overwrite anything + * + * @param string $dir + * @param string $filename + * @return string + */ +function findUnusedFilename($dir, $filename) { + $unique = "$dir/$filename"; + if (file_exists($unique)) { + $unique = tempnam($dir, "$filename."); + unlink($unique); + } + return $unique; +} + +/** + * Execute a composer command, reload $composerData afterwards, and check for repo authentication warnings + * + * @param string $command + * @return array Command output split by lines + * @throws RuntimeException + */ +function runComposer($command) +{ + global $composerExec, $composerData, $composerFile, $authFailed; + $command = "$composerExec $command --no-interaction"; + output(" Running command:\\n $command"); + exec("$command 2>&1", $lines, $exitCode); + $output = ' ' . join('\n ', $lines); + + // Reload composer object from the updated composer.json + $composerData = json_decode(file_get_contents($composerFile), true); + + if (0 !== $exitCode) { + $output = "Error encountered running command:\\n $command\\n$output"; + throw new RuntimeException($output, $exitCode); + } + output($output); + + if (strpos($output, 'URL required authentication.') !== false) { + preg_match("/'(https?:\/\/)?(?<url>[^\/']+)(\/[^']*)?' URL required authentication/", $output, $matches); + $authUrl = $matches['url']; + $authFailed[$authUrl] = 1; + output("Repository authentication failed; make sure '$authUrl' exists in auth.json", WARN); + } + + return $lines; +} + +/** + * Deletes a file or a directory and all its contents + * + * @param string $path + * @throws Exception + */ +function deleteFilepath($path) { + if (!file_exists($path)) { + return; + } + if (is_dir($path)) { + $files = array_diff(scandir($path), array('..', '.')); + foreach ($files as $file) { + deleteFilepath("$path/$file"); + } + rmdir($path); + } + else { + unlink($path); + } + if (file_exists($path)) { + throw new Exception("Failed to delete $path"); + } +} + +/** + * Logs the given text with \n newline replacement and log level formatting + * + * @param string $string Text to log + * @param int $level One of INFO, WARN, or ERROR + * @param string $label Optional message label; defaults to WARNING for $level = WARN and ERROR for $level = ERROR + */ +function output($string, $level = INFO, $label = '') { + $string = str_replace('\n', PHP_EOL, $string); + + if (!empty($label)) { + $label = "$label: "; + } + else if ($level == WARN) { + $label = 'WARNING: '; + } + else if ($level == ERROR) { + $label = 'ERROR: '; + } + $string = "$label$string"; + + if ($level == WARN) { + error_log($string); + } + elseif ($level == ERROR) { + error_log(PHP_EOL . $string); + } + else { + echo $string . PHP_EOL; + } +} diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php index b663a3a2f733c..c9f10c183b50c 100644 --- a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php @@ -72,6 +72,15 @@ private function addFilterGroupToCollection( if (!$isApplied) { $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; $fields[] = $this->getFieldMapping($filter->getField()); + + if ($condition === 'fulltext') { + // NOTE: This is not a fulltext search, but the best way to search something when + // a SearchCriteria with "fulltext" condition is provided over a MySQL table + // (see https://github.com/magento-engcom/msi/issues/1221) + $condition = 'like'; + $filter->setValue('%' . $filter->getValue() . '%'); + } + $conditions[] = [$condition => $filter->getValue()]; } } diff --git a/lib/internal/Magento/Framework/App/Utility/Files.php b/lib/internal/Magento/Framework/App/Utility/Files.php index 7e8d79eead7e1..b0dfc50e9f972 100644 --- a/lib/internal/Magento/Framework/App/Utility/Files.php +++ b/lib/internal/Magento/Framework/App/Utility/Files.php @@ -392,7 +392,7 @@ public function getMainConfigFiles($asDataSet = true) $configXmlPaths = array_merge($globPaths, $configXmlPaths); $files = []; foreach ($configXmlPaths as $xmlPath) { - $files = array_merge($files, glob($xmlPath)); + $files = array_merge($files, glob($xmlPath, GLOB_NOSORT)); } self::$_cache[$cacheKey] = $files; } diff --git a/lib/internal/Magento/Framework/Archive/Tar.php b/lib/internal/Magento/Framework/Archive/Tar.php index ccf9838d6649f..e2a070503f61f 100644 --- a/lib/internal/Magento/Framework/Archive/Tar.php +++ b/lib/internal/Magento/Framework/Archive/Tar.php @@ -252,7 +252,7 @@ protected function _createTar($skipRoot = false, $finalize = false) $file = $this->_getCurrentFile(); if (is_dir($file)) { - $dirFiles = scandir($file); + $dirFiles = scandir($file, SCANDIR_SORT_NONE); if (false === $dirFiles) { throw new \Magento\Framework\Exception\LocalizedException( diff --git a/lib/internal/Magento/Framework/Backup/Test/Unit/_files/app_dirs_rollback.php b/lib/internal/Magento/Framework/Backup/Test/Unit/_files/app_dirs_rollback.php index 7a9814bcd6932..5d4f18037d023 100644 --- a/lib/internal/Magento/Framework/Backup/Test/Unit/_files/app_dirs_rollback.php +++ b/lib/internal/Magento/Framework/Backup/Test/Unit/_files/app_dirs_rollback.php @@ -15,7 +15,7 @@ } } -$files = glob(TESTS_TEMP_DIR . '/Magento/Backup/data/*'); +$files = glob(TESTS_TEMP_DIR . '/Magento/Backup/data/*', GLOB_NOSORT); foreach ($files as $file) { unlink($file); } diff --git a/lib/internal/Magento/Framework/Bulk/OperationInterface.php b/lib/internal/Magento/Framework/Bulk/OperationInterface.php index 4b626ac659626..c1cac9f171430 100644 --- a/lib/internal/Magento/Framework/Bulk/OperationInterface.php +++ b/lib/internal/Magento/Framework/Bulk/OperationInterface.php @@ -10,7 +10,7 @@ * @api * @since 100.2.0 */ -interface OperationInterface +interface OperationInterface extends \Magento\Framework\Api\ExtensibleDataInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case diff --git a/lib/internal/Magento/Framework/Data/Collection/Filesystem.php b/lib/internal/Magento/Framework/Data/Collection/Filesystem.php index 67d2a020864dd..330ff4e975e8a 100644 --- a/lib/internal/Magento/Framework/Data/Collection/Filesystem.php +++ b/lib/internal/Magento/Framework/Data/Collection/Filesystem.php @@ -243,7 +243,7 @@ protected function _collectRecursive($dir) $dir = [$dir]; } foreach ($dir as $folder) { - if ($nodes = glob($folder . '/*')) { + if ($nodes = glob($folder . '/*', GLOB_NOSORT)) { foreach ($nodes as $node) { $collectedResult[] = $node; } diff --git a/lib/internal/Magento/Framework/Filesystem/Io/File.php b/lib/internal/Magento/Framework/Filesystem/Io/File.php index 7849fdf31031f..c1cfebc7a0ac1 100644 --- a/lib/internal/Magento/Framework/Filesystem/Io/File.php +++ b/lib/internal/Magento/Framework/Filesystem/Io/File.php @@ -366,7 +366,7 @@ protected static function _recursiveCallback($dir, array $fileCallback, array $d $dirCallback = $fileCallback; } if (is_dir($dir)) { - foreach (scandir($dir) as $item) { + foreach (scandir($dir, SCANDIR_SORT_NONE) as $item) { if (!strcmp($item, '.') || !strcmp($item, '..')) { continue; } diff --git a/lib/internal/Magento/Framework/Logger/Handler/Syslog.php b/lib/internal/Magento/Framework/Logger/Handler/Syslog.php new file mode 100644 index 0000000000000..4964cc45f85d7 --- /dev/null +++ b/lib/internal/Magento/Framework/Logger/Handler/Syslog.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Logger\Handler; + +use Monolog\Handler\SyslogHandler; +use Monolog\Logger; + +/** + * @inheritdoc + */ +class Syslog extends SyslogHandler +{ + private const FACILITY = LOG_USER; + private const LEVEL = Logger::DEBUG; + + /** + * @param string $ident The string ident to be added to each message + */ + public function __construct(string $ident) + { + parent::__construct($ident, self::FACILITY, self::LEVEL); + } +} diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/DataObject.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/DataObject.php index 6816ecdbdf71c..9aada9d5dbe41 100644 --- a/lib/internal/Magento/Framework/Reflection/Test/Unit/DataObject.php +++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/DataObject.php @@ -5,6 +5,8 @@ */ namespace Magento\Framework\Reflection\Test\Unit; +use Magento\Framework\Reflection\Test\Unit\Fixture\TSampleInterface; + /** * Dummy data object to be used by TypeProcessorTest */ @@ -13,18 +15,23 @@ class DataObject /** * @var string */ - protected $attrName; + private $attrName; /** * @var bool */ - protected $isActive; + private $isActive; /** * @var string */ private $name; + /** + * @var array + */ + private $data = []; + /** * @return string */ @@ -70,4 +77,32 @@ public function setName($name = null) $this->name = $name; return $this; } + + /** + * @param string $key Key is used as index + * @param string $value + * @return void + */ + public function setData(string $key, string $value) + { + $this->data[$key] = $value; + } + + /** + * @param array $data + * @return void + */ + public function addData(array $data) + { + $this->data = $data; + } + + /** + * @param TSampleInterface[] $list + * @return void + */ + public function addObjectList(array $list) + { + $this->data['objects'] = $list; + } } diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php index 4543b3b6eec12..4a61d003e32a8 100644 --- a/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php +++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php @@ -8,24 +8,22 @@ use Magento\Framework\Exception\SerializationException; use Magento\Framework\Reflection\Test\Unit\Fixture\TSample; +use Magento\Framework\Reflection\TypeProcessor; use Zend\Code\Reflection\ClassReflection; -/** - * Type processor Test - */ class TypeProcessorTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Framework\Reflection\TypeProcessor + * @var TypeProcessor */ - protected $_typeProcessor; + private $typeProcessor; /** * Set up helper. */ protected function setUp() { - $this->_typeProcessor = new \Magento\Framework\Reflection\TypeProcessor(); + $this->typeProcessor = new TypeProcessor(); } /** @@ -33,11 +31,11 @@ protected function setUp() */ public function testGetTypesData() { - $this->_typeProcessor->setTypeData('typeA', ['dataA']); - $this->_typeProcessor->setTypeData('typeB', ['dataB']); + $this->typeProcessor->setTypeData('typeA', ['dataA']); + $this->typeProcessor->setTypeData('typeB', ['dataB']); $this->assertEquals( ['typeA' => ['dataA'], 'typeB' => ['dataB']], - $this->_typeProcessor->getTypesData() + $this->typeProcessor->getTypesData() ); } @@ -46,11 +44,11 @@ public function testGetTypesData() */ public function testSetTypesData() { - $this->_typeProcessor->setTypeData('typeC', ['dataC']); - $this->assertEquals(['typeC' => ['dataC']], $this->_typeProcessor->getTypesData()); + $this->typeProcessor->setTypeData('typeC', ['dataC']); + $this->assertEquals(['typeC' => ['dataC']], $this->typeProcessor->getTypesData()); $typeData = ['typeA' => ['dataA'], 'typeB' => ['dataB']]; - $this->_typeProcessor->setTypesData($typeData); - $this->assertEquals($typeData, $this->_typeProcessor->getTypesData()); + $this->typeProcessor->setTypesData($typeData); + $this->assertEquals($typeData, $this->typeProcessor->getTypesData()); } /** @@ -59,7 +57,7 @@ public function testSetTypesData() */ public function testGetTypeDataInvalidArgumentException() { - $this->_typeProcessor->getTypeData('NonExistentType'); + $this->typeProcessor->getTypeData('NonExistentType'); } /** @@ -67,8 +65,8 @@ public function testGetTypeDataInvalidArgumentException() */ public function testGetTypeData() { - $this->_typeProcessor->setTypeData('typeA', ['dataA']); - $this->assertEquals(['dataA'], $this->_typeProcessor->getTypeData('typeA')); + $this->typeProcessor->setTypeData('typeA', ['dataA']); + $this->assertEquals(['dataA'], $this->typeProcessor->getTypeData('typeA')); } /** @@ -76,85 +74,88 @@ public function testGetTypeData() */ public function testSetTypeDataArrayMerge() { - $this->_typeProcessor->setTypeData('typeA', ['dataA1']); - $this->_typeProcessor->setTypeData('typeA', ['dataA2']); - $this->_typeProcessor->setTypeData('typeA', ['dataA3']); - $this->_typeProcessor->setTypeData('typeA', [null]); - $this->assertEquals(['dataA1', 'dataA2', 'dataA3', null], $this->_typeProcessor->getTypeData('typeA')); + $this->typeProcessor->setTypeData('typeA', ['dataA1']); + $this->typeProcessor->setTypeData('typeA', ['dataA2']); + $this->typeProcessor->setTypeData('typeA', ['dataA3']); + $this->typeProcessor->setTypeData('typeA', [null]); + $this->assertEquals( + ['dataA1', 'dataA2', 'dataA3', null], + $this->typeProcessor->getTypeData('typeA') + ); } public function testNormalizeType() { - $this->assertEquals('blah', $this->_typeProcessor->normalizeType('blah')); - $this->assertEquals('string', $this->_typeProcessor->normalizeType('str')); - $this->assertEquals('int', $this->_typeProcessor->normalizeType('integer')); - $this->assertEquals('boolean', $this->_typeProcessor->normalizeType('bool')); - $this->assertEquals('anyType', $this->_typeProcessor->normalizeType('mixed')); + $this->assertEquals('blah', $this->typeProcessor->normalizeType('blah')); + $this->assertEquals('string', $this->typeProcessor->normalizeType('str')); + $this->assertEquals('int', $this->typeProcessor->normalizeType('integer')); + $this->assertEquals('boolean', $this->typeProcessor->normalizeType('bool')); + $this->assertEquals('anyType', $this->typeProcessor->normalizeType('mixed')); } public function testIsTypeSimple() { - $this->assertTrue($this->_typeProcessor->isTypeSimple('string')); - $this->assertTrue($this->_typeProcessor->isTypeSimple('string[]')); - $this->assertTrue($this->_typeProcessor->isTypeSimple('int')); - $this->assertTrue($this->_typeProcessor->isTypeSimple('float')); - $this->assertTrue($this->_typeProcessor->isTypeSimple('double')); - $this->assertTrue($this->_typeProcessor->isTypeSimple('boolean')); - $this->assertFalse($this->_typeProcessor->isTypeSimple('blah')); + $this->assertTrue($this->typeProcessor->isTypeSimple('string')); + $this->assertTrue($this->typeProcessor->isTypeSimple('string[]')); + $this->assertTrue($this->typeProcessor->isTypeSimple('int')); + $this->assertTrue($this->typeProcessor->isTypeSimple('float')); + $this->assertTrue($this->typeProcessor->isTypeSimple('double')); + $this->assertTrue($this->typeProcessor->isTypeSimple('boolean')); + $this->assertFalse($this->typeProcessor->isTypeSimple('blah')); } public function testIsTypeAny() { - $this->assertTrue($this->_typeProcessor->isTypeAny('mixed')); - $this->assertTrue($this->_typeProcessor->isTypeAny('mixed[]')); - $this->assertFalse($this->_typeProcessor->isTypeAny('int')); - $this->assertFalse($this->_typeProcessor->isTypeAny('int[]')); + $this->assertTrue($this->typeProcessor->isTypeAny('mixed')); + $this->assertTrue($this->typeProcessor->isTypeAny('mixed[]')); + $this->assertFalse($this->typeProcessor->isTypeAny('int')); + $this->assertFalse($this->typeProcessor->isTypeAny('int[]')); } public function testIsArrayType() { - $this->assertFalse($this->_typeProcessor->isArrayType('string')); - $this->assertTrue($this->_typeProcessor->isArrayType('string[]')); + $this->assertFalse($this->typeProcessor->isArrayType('string')); + $this->assertTrue($this->typeProcessor->isArrayType('string[]')); } public function testIsValidTypeDeclaration() { - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('Traversable')); // Interface - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('stdObj')); // Class - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('array')); - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('callable')); - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('self')); - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('self')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('string')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('string[]')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('int')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('float')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('double')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('boolean')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('[]')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('mixed[]')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('stdObj[]')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('Traversable[]')); + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('Traversable')); // Interface + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('stdObj')); // Class + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('array')); + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('callable')); + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('self')); + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('self')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('string')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('string[]')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('int')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('float')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('double')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('boolean')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('[]')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('mixed[]')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('stdObj[]')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('Traversable[]')); } public function getArrayItemType() { - $this->assertEquals('string', $this->_typeProcessor->getArrayItemType('str[]')); - $this->assertEquals('string', $this->_typeProcessor->getArrayItemType('string[]')); - $this->assertEquals('integer', $this->_typeProcessor->getArrayItemType('int[]')); - $this->assertEquals('boolean', $this->_typeProcessor->getArrayItemType('bool[]')); - $this->assertEquals('any', $this->_typeProcessor->getArrayItemType('mixed[]')); + $this->assertEquals('string', $this->typeProcessor->getArrayItemType('str[]')); + $this->assertEquals('string', $this->typeProcessor->getArrayItemType('string[]')); + $this->assertEquals('integer', $this->typeProcessor->getArrayItemType('int[]')); + $this->assertEquals('boolean', $this->typeProcessor->getArrayItemType('bool[]')); + $this->assertEquals('any', $this->typeProcessor->getArrayItemType('mixed[]')); } public function testTranslateTypeName() { $this->assertEquals( 'TestModule1V1EntityItem', - $this->_typeProcessor->translateTypeName(\Magento\TestModule1\Service\V1\Entity\Item::class) + $this->typeProcessor->translateTypeName(\Magento\TestModule1\Service\V1\Entity\Item::class) ); $this->assertEquals( 'TestModule3V1EntityParameter[]', - $this->_typeProcessor->translateTypeName('\Magento\TestModule3\Service\V1\Entity\Parameter[]') + $this->typeProcessor->translateTypeName('\Magento\TestModule3\Service\V1\Entity\Parameter[]') ); } @@ -164,47 +165,47 @@ public function testTranslateTypeName() */ public function testTranslateTypeNameInvalidArgumentException() { - $this->_typeProcessor->translateTypeName('\Magento\TestModule3\V1\Parameter[]'); + $this->typeProcessor->translateTypeName('\Magento\TestModule3\V1\Parameter[]'); } public function testTranslateArrayTypeName() { - $this->assertEquals('ArrayOfComplexType', $this->_typeProcessor->translateArrayTypeName('complexType')); + $this->assertEquals('ArrayOfComplexType', $this->typeProcessor->translateArrayTypeName('complexType')); } public function testProcessSimpleTypeIntToString() { $value = 1; $type = 'string'; - $this->assertSame('1', $this->_typeProcessor->processSimpleAndAnyType($value, $type)); + $this->assertSame('1', $this->typeProcessor->processSimpleAndAnyType($value, $type)); } public function testProcessSimpleTypeStringToInt() { $value = '1'; $type = 'int'; - $this->assertSame(1, $this->_typeProcessor->processSimpleAndAnyType($value, $type)); + $this->assertSame(1, $this->typeProcessor->processSimpleAndAnyType($value, $type)); } public function testProcessSimpleTypeMixed() { $value = 1; $type = 'mixed'; - $this->assertSame(1, $this->_typeProcessor->processSimpleAndAnyType($value, $type)); + $this->assertSame(1, $this->typeProcessor->processSimpleAndAnyType($value, $type)); } public function testProcessSimpleTypeIntArrayToStringArray() { $value = [1, 2, 3, 4, 5]; $type = 'string[]'; - $this->assertSame(['1', '2', '3', '4', '5'], $this->_typeProcessor->processSimpleAndAnyType($value, $type)); + $this->assertSame(['1', '2', '3', '4', '5'], $this->typeProcessor->processSimpleAndAnyType($value, $type)); } public function testProcessSimpleTypeStringArrayToIntArray() { $value = ['1', '2', '3', '4', '5']; $type = 'int[]'; - $this->assertSame([1, 2, 3, 4, 5], $this->_typeProcessor->processSimpleAndAnyType($value, $type)); + $this->assertSame([1, 2, 3, 4, 5], $this->typeProcessor->processSimpleAndAnyType($value, $type)); } /** @@ -212,10 +213,11 @@ public function testProcessSimpleTypeStringArrayToIntArray() */ public function testProcessSimpleTypeException($value, $type) { - $this->expectException(SerializationException::class); - $this->expectExceptionMessage('The "' - . $value . '" value\'s type is invalid. The "' . $type . '" type was expected. Verify and try again.'); - $this->_typeProcessor->processSimpleAndAnyType($value, $type); + $this->expectException( + SerializationException::class, + 'Invalid type for value: "' . $value . '". Expected Type: "' . $type . '"' + ); + $this->typeProcessor->processSimpleAndAnyType($value, $type); } public static function processSimpleTypeExceptionProvider() @@ -234,32 +236,89 @@ public function testProcessSimpleTypeInvalidType() { $value = 1; $type = 'int[]'; - $this->_typeProcessor->processSimpleAndAnyType($value, $type); + $this->typeProcessor->processSimpleAndAnyType($value, $type); } /** * @expectedException \LogicException * @expectedExceptionMessageRegExp /@param annotation is incorrect for the parameter "name" \w+/ */ - public function testGetParamType() + public function testGetParamTypeWithIncorrectAnnotation() { - $class = new ClassReflection(\Magento\Framework\Reflection\Test\Unit\DataObject::class); + $class = new ClassReflection(DataObject::class); $methodReflection = $class->getMethod('setName'); $paramsReflection = $methodReflection->getParameters(); - $this->_typeProcessor->getParamType($paramsReflection[0]); + $this->typeProcessor->getParamType($paramsReflection[0]); } - public function testGetParameterDescription() + /** + * Checks a case for different array param types. + * + * @param string $methodName + * @param string $type + * @dataProvider arrayParamTypeDataProvider + */ + public function testGetArrayParamType(string $methodName, string $type) { - $class = new ClassReflection(\Magento\Framework\Reflection\Test\Unit\DataObject::class); - $methodReflection = $class->getMethod('setName'); + $class = new ClassReflection(DataObject::class); + $methodReflection = $class->getMethod($methodName); + $params = $methodReflection->getParameters(); + $this->assertEquals($type, $this->typeProcessor->getParamType(array_pop($params))); + } + + /** + * Get list of methods with expected param types. + * + * @return array + */ + public function arrayParamTypeDataProvider() + { + return [ + ['method name' => 'addData', 'type' => 'array[]'], + ['method name' => 'addObjectList', 'type' => 'TSampleInterface[]'] + ]; + } + + /** + * Checks a case when method param has additional description. + * + * @param string $methodName + * @param array $descriptions + * @dataProvider methodParamsDataProvider + */ + public function testGetParameterDescription(string $methodName, array $descriptions) + { + $class = new ClassReflection(DataObject::class); + $methodReflection = $class->getMethod($methodName); $paramsReflection = $methodReflection->getParameters(); - $this->assertEquals('Name of the attribute', $this->_typeProcessor->getParamDescription($paramsReflection[0])); + foreach ($paramsReflection as $paramReflection) { + $description = array_shift($descriptions); + $this->assertEquals( + $description, + $this->typeProcessor->getParamDescription($paramReflection) + ); + } + } + + /** + * Gets list of method names with params and their descriptions. + * + * @return array + */ + public function methodParamsDataProvider() + { + return [ + ['method name' => 'setName', 'descriptions' => ['Name of the attribute']], + ['method name' => 'setData', 'descriptions' => ['Key is used as index', null]], + ]; } public function testGetOperationName() { - $this->assertEquals("resNameMethodName", $this->_typeProcessor->getOperationName("resName", "methodName")); + $this->assertEquals( + "resNameMethodName", + $this->typeProcessor->getOperationName("resName", "methodName") + ); } /** @@ -277,19 +336,19 @@ public function testGetReturnTypeWithInheritDocBlock() $classReflection = new ClassReflection(TSample::class); $methodReflection = $classReflection->getMethod('getPropertyName'); - self::assertEquals($expected, $this->_typeProcessor->getGetterReturnType($methodReflection)); + self::assertEquals($expected, $this->typeProcessor->getGetterReturnType($methodReflection)); } /** * Checks a case when method and parent interface don't have `@return` annotation. * * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Getter return type must be specified using @return annotation. See Magento\Framework\Reflection\Test\Unit\Fixture\TSample::getName() + * @expectedExceptionMessage Method's return type must be specified using @return annotation. See Magento\Framework\Reflection\Test\Unit\Fixture\TSample::getName() */ public function testGetReturnTypeWithoutReturnTag() { $classReflection = new ClassReflection(TSample::class); $methodReflection = $classReflection->getMethod('getName'); - $this->_typeProcessor->getGetterReturnType($methodReflection); + $this->typeProcessor->getGetterReturnType($methodReflection); } } diff --git a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php index 80285853b43c6..d7206032c68c7 100644 --- a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php +++ b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php @@ -9,6 +9,7 @@ use Magento\Framework\Exception\SerializationException; use Magento\Framework\Phrase; use Zend\Code\Reflection\ClassReflection; +use Zend\Code\Reflection\DocBlock\Tag\ParamTag; use Zend\Code\Reflection\DocBlock\Tag\ReturnTag; use Zend\Code\Reflection\DocBlockReflection; use Zend\Code\Reflection\MethodReflection; @@ -522,35 +523,24 @@ public function getParamType(ParameterReflection $param) } if ($type == 'array') { // try to determine class, if it's array of objects - $docBlock = $param->getDeclaringFunction()->getDocBlock(); - $pattern = "/\@param\s+([\w\\\_]+\[\])\s+\\\${$param->getName()}\n/"; - $matches = []; - if (preg_match($pattern, $docBlock->getContents(), $matches)) { - return $matches[1]; - } - return "{$type}[]"; + $paramDocBlock = $this->getParamDocBlockTag($param); + $paramTypes = $paramDocBlock->getTypes(); + $paramType = array_shift($paramTypes); + return strpos($paramType, '[]') !== false ? $paramType : "{$paramType}[]"; } return $type; } /** - * Get parameter description + * Gets method parameter description. * * @param ParameterReflection $param * @return string|null */ public function getParamDescription(ParameterReflection $param) { - $docBlock = $param->getDeclaringFunction()->getDocBlock(); - $docBlockLines = explode("\n", $docBlock->getContents()); - $pattern = "/\@param\s+([\w\\\_\[\]\|]+)\s+(\\\${$param->getName()})\s(.*)/"; - $matches = []; - - foreach ($docBlockLines as $line) { - if (preg_match($pattern, $line, $matches)) { - return $matches[3]; - } - } + $paramDocBlock = $this->getParamDocBlockTag($param); + return $paramDocBlock->getDescription(); } /** @@ -731,7 +721,7 @@ private function getMethodReturnAnnotation(MethodReflection $methodReflection) // throw an exception if even implemented interface doesn't have return annotations if (empty($returnAnnotations)) { throw new \InvalidArgumentException( - "Getter return type must be specified using @return annotation. " + "Method's return type must be specified using @return annotation. " . "See {$methodReflection->getDeclaringClass()->getName()}::{$methodName}()" ); } @@ -750,10 +740,24 @@ private function getReturnFromDocBlock(MethodReflection $methodReflection) $methodDocBlock = $methodReflection->getDocBlock(); if (!$methodDocBlock) { throw new \InvalidArgumentException( - "Each getter must have a doc block. " + "Each method must have a doc block. " . "See {$methodReflection->getDeclaringClass()->getName()}::{$methodReflection->getName()}()" ); } return current($methodDocBlock->getTags('return')); } + + /** + * Gets method's param doc block. + * + * @param ParameterReflection $param + * @return ParamTag + */ + private function getParamDocBlockTag(ParameterReflection $param): ParamTag + { + $docBlock = $param->getDeclaringFunction() + ->getDocBlock(); + $paramsTag = $docBlock->getTags('param'); + return $paramsTag[$param->getPosition()]; + } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php index 7f73e742e0a6c..830fcb293a8f1 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php @@ -5,7 +5,9 @@ */ namespace Magento\Framework\Setup\Declaration\Schema\Declaration; +use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\Phrase; +use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; use Magento\Framework\Stdlib\BooleanUtils; use Magento\Framework\Setup\Exception; use Magento\Framework\Setup\Declaration\Schema\Dto\Column; @@ -66,6 +68,11 @@ class SchemaBuilder */ private $resourceConnection; + /** + * @var TableNameResolver + */ + private $tableNameResolver; + /** * SchemaBuilder constructor. * @@ -74,6 +81,7 @@ class SchemaBuilder * @param Sharding $sharding * @param ValidationComposite $validationComposite * @param \Magento\Framework\App\ResourceConnection $resourceConnection + * @param TableNameResolver $tableNameResolver * @internal param array $tablesData */ public function __construct( @@ -81,13 +89,15 @@ public function __construct( BooleanUtils $booleanUtils, Sharding $sharding, ValidationComposite $validationComposite, - \Magento\Framework\App\ResourceConnection $resourceConnection + \Magento\Framework\App\ResourceConnection $resourceConnection, + TableNameResolver $tableNameResolver ) { $this->sharding = $sharding; $this->elementFactory = $elementFactory; $this->booleanUtils = $booleanUtils; $this->validationComposite = $validationComposite; $this->resourceConnection = $resourceConnection; + $this->tableNameResolver = $tableNameResolver; } /** @@ -275,6 +285,35 @@ private function convertColumnNamesToObjects(array $columnNames, Table $table) return $columns; } + /** + * Provides the full index name based on the prefix value. + * + * @param string $name + * @param Table $table + * @param array $columns + * @param string $type + * @return string + */ + private function getFullIndexName( + string $name, + Table $table, + array $columns, + string $type = AdapterInterface::INDEX_TYPE_INDEX + ) { + if (AdapterInterface::INDEX_TYPE_PRIMARY === $type) { + return $name; + } + + $tableName = $this->tableNameResolver->getNameOfOriginTable($table->getName()); + + return $this->resourceConnection + ->getIdxName( + $tableName, + $columns, + $type + ); + } + /** * Convert and instantiate index objects. * @@ -296,6 +335,21 @@ private function processIndexes(array $tableData, $resource, Table $table) continue; } + /** + * Temporary solution. + * @see MAGETWO-91365 + */ + $indexType = AdapterInterface::INDEX_TYPE_INDEX; + if (isset($indexData['indexType']) && $indexData['indexType'] === AdapterInterface::INDEX_TYPE_FULLTEXT) { + $indexType = $indexData['indexType']; + } + + $indexData['name'] = $this->getFullIndexName( + $indexData['name'], + $table, + $indexData['column'], + $indexType + ); $indexData = $this->processGenericData($indexData, $resource, $table); $indexData['columns'] = $this->convertColumnNamesToObjects($indexData['column'], $table); $index = $this->elementFactory->create('index', $indexData); @@ -354,9 +408,25 @@ private function processConstraints(array $tableData, $resource, Schema $schema, $constraintData['referenceColumn'], $constraintData['referenceTable'] ); + /** + * Calculation of the full name of Foreign Key based on the prefix value. + */ + $constraintData['name'] = $this->resourceConnection + ->getFkName( + $this->tableNameResolver->getNameOfOriginTable($table->getName()), + $constraintData['column']->getName(), + $constraintData['referenceTable']->getName(), + $constraintData['referenceColumn']->getName() + ); $constraint = $this->elementFactory->create($constraintData['type'], $constraintData); $constraints[$constraint->getName()] = $constraint; } else { + $constraintData['name'] = $this->getFullIndexName( + $constraintData['name'], + $table, + $constraintData['column'], + $constraintData['type'] + ); $constraintData['columns'] = $this->convertColumnNamesToObjects($constraintData['column'], $table); $constraint = $this->elementFactory->create($constraintData['type'], $constraintData); $constraints[$constraint->getName()] = $constraint; diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/Diff.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/Diff.php index cb222d8b0c3d1..0e857567689c4 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/Diff.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/Diff.php @@ -7,8 +7,10 @@ namespace Magento\Framework\Setup\Declaration\Schema\Diff; use Magento\Framework\Component\ComponentRegistrar; +use Magento\Framework\Setup\Declaration\Schema\Dto\Constraint; use Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Reference; use Magento\Framework\Setup\Declaration\Schema\Dto\ElementInterface; +use Magento\Framework\Setup\Declaration\Schema\Dto\Index; use Magento\Framework\Setup\Declaration\Schema\Dto\Table; use Magento\Framework\Setup\Declaration\Schema\Dto\TableElementInterface; use Magento\Framework\Setup\Declaration\Schema\ElementHistory; @@ -158,20 +160,41 @@ private function getWhiteListTables() * @param string $operation * @return bool */ - public function canBeRegistered(ElementInterface $object, $operation) + public function canBeRegistered(ElementInterface $object, $operation): bool { if (!isset($this->destructiveOperations[$operation])) { return true; } + $checkResult = false; $whiteList = $this->getWhiteListTables(); - $type = $object->getElementType(); if ($object instanceof TableElementInterface) { - return isset($whiteList[$object->getTable()->getNameWithoutPrefix()][$type][$object->getName()]); + $tableNameWithoutPrefix = $object->getTable()->getNameWithoutPrefix(); + $type = $object->getElementType(); + + if ($this->isElementHaveAutoGeneratedName($object)) { + $checkResult = + isset($whiteList[$tableNameWithoutPrefix][$type][$object->getNameWithoutPrefix()]); + } else { + $checkResult = isset($whiteList[$tableNameWithoutPrefix][$type][$object->getName()]); + } + } elseif ($object instanceof Table) { + $checkResult = isset($whiteList[$object->getNameWithoutPrefix()]); } - return isset($whiteList[$object->getNameWithoutPrefix()]); + return $checkResult; + } + + /** + * Check if the element has an auto-generated name. + * + * @param ElementInterface $element + * @return bool + */ + private function isElementHaveAutoGeneratedName(ElementInterface $element): bool + { + return in_array($element->getElementType(), [Index::TYPE, Constraint::TYPE], true); } /** diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/TableDiff.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/TableDiff.php index 2030b192935e7..87045df864a3e 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/TableDiff.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/TableDiff.php @@ -7,10 +7,10 @@ namespace Magento\Framework\Setup\Declaration\Schema\Diff; use Magento\Framework\Setup\Declaration\Schema\Dto\Column; +use Magento\Framework\Setup\Declaration\Schema\Dto\Constraint; use Magento\Framework\Setup\Declaration\Schema\Dto\ElementInterface; use Magento\Framework\Setup\Declaration\Schema\Dto\Index; use Magento\Framework\Setup\Declaration\Schema\Dto\Table; -use Magento\Framework\Setup\Declaration\Schema\Operations\AddComplexElement; use Magento\Framework\Setup\Declaration\Schema\Operations\ModifyColumn; /** @@ -91,12 +91,14 @@ private function turnOffForeignKeys(Table $declaredTable, Table $generatedTable, if ($elementHistory->getNew() instanceof Column) { $column = $elementHistory->getNew(); $references = $generatedTable->getReferenceConstraints(); - $declaredReferences = $declaredTable->getReferenceConstraints(); + $declaredReferences = $this->getElementsListByNameWithoutPrefix( + $declaredTable->getReferenceConstraints() + ); foreach ($references as $reference) { /** In case when we have foreign key on column, that should be modified */ if ($reference->getColumn()->getName() === $column->getName() && - isset($declaredReferences[$reference->getName()]) + isset($declaredReferences[$reference->getNameWithoutPrefix()]) ) { /** * Lets disable foreign key and enable it again @@ -104,7 +106,11 @@ private function turnOffForeignKeys(Table $declaredTable, Table $generatedTable, * we will drop key, modify column, add key */ $diff = $this->diffManager->registerRemoval($diff, [$reference]); - $diff = $this->diffManager->registerCreation($diff, $reference); + $diff = $this->diffManager + ->registerCreation( + $diff, + $declaredReferences[$reference->getNameWithoutPrefix()] + ); } } } @@ -113,6 +119,22 @@ private function turnOffForeignKeys(Table $declaredTable, Table $generatedTable, return $diff; } + /** + * Switches keys of the array on the element name without prefix. + * + * @param Constraint[]|Index[] $elements + * @return array + */ + private function getElementsListByNameWithoutPrefix(array $elements) + { + $elementsList = []; + foreach ($elements as $element) { + $elementsList[$element->getNameWithoutPrefix()] = $element; + } + + return $elementsList; + } + /** * Diff between tables. * @@ -135,6 +157,19 @@ public function diff( $this->diffManager->registerTableModification($declaredTable, $generatedTable, $diff); } + return $this->calculateDiff($declaredTable, $generatedTable, $diff); + } + + /** + * Calculate the difference between tables. + * + * @param Table|ElementInterface $declaredTable + * @param Table|ElementInterface $generatedTable + * @param Diff $diff + * @return Diff + */ + private function calculateDiff(ElementInterface $declaredTable, ElementInterface $generatedTable, Diff $diff) + { $types = [self::COLUMN_DIFF_TYPE, self::CONSTRAINT_DIFF_TYPE, self::INDEX_DIFF_TYPE]; //We do inspection for each element type foreach ($types as $elementType) { @@ -146,6 +181,11 @@ public function diff( $declaredElements = $this->excludeAutoIndexes($declaredTable, $declaredElements); } + if (in_array($elementType, [self::CONSTRAINT_DIFF_TYPE, self::INDEX_DIFF_TYPE], true)) { + $generatedElements = $this->getElementsListByNameWithoutPrefix($generatedElements); + $declaredElements = $this->getElementsListByNameWithoutPrefix($declaredElements); + } + foreach ($declaredElements as $elementName => $element) { //If it is new for generated (generated from db) elements - we need to create it if (!isset($generatedElements[$elementName])) { @@ -169,6 +209,7 @@ public function diff( } $diff = $this->turnOffForeignKeys($declaredTable, $generatedTable, $diff); + return $diff; } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraint.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraint.php index a7f7fcb2e6656..9f03c1c20cf49 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraint.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraint.php @@ -34,20 +34,28 @@ class Constraint extends GenericElement implements */ private $table; + /** + * @var string + */ + private $nameWithoutPrefix; + /** * Constructor. * * @param string $name * @param string $type - * @param Table $table + * @param Table $table + * @param string $nameWithoutPrefix */ public function __construct( string $name, string $type, - Table $table + Table $table, + string $nameWithoutPrefix ) { parent::__construct($name, $type); $this->table = $table; + $this->nameWithoutPrefix = $nameWithoutPrefix; } /** @@ -67,4 +75,14 @@ public function getElementType() { return self::TYPE; } + + /** + * Retrieve the constraint name which is calculated without table prefix. + * + * @return string + */ + public function getNameWithoutPrefix() + { + return $this->nameWithoutPrefix; + } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Internal.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Internal.php index e15407a4a837d..486d43c023c7f 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Internal.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Internal.php @@ -31,16 +31,18 @@ class Internal extends Constraint implements ElementDiffAwareInterface * * @param string $name * @param string $type - * @param Table $table - * @param array $columns + * @param Table $table + * @param string $nameWithoutPrefix + * @param array $columns */ public function __construct( $name, $type, Table $table, + string $nameWithoutPrefix, array $columns ) { - parent::__construct($name, $type, $table); + parent::__construct($name, $type, $table, $nameWithoutPrefix); $this->columns = $columns; } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Reference.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Reference.php index b79e8fdd3cc2f..b5c8d16311448 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Reference.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Reference.php @@ -46,9 +46,10 @@ class Reference extends Constraint implements ElementDiffAwareInterface * * @param string $name * @param string $type - * @param Table $table + * @param Table $table + * @param string $nameWithoutPrefix * @param Column $column - * @param Table $referenceTable + * @param Table $referenceTable * @param Column $referenceColumn * @param string $onDelete * @SuppressWarnings(Magento.TypeDuplication) @@ -57,12 +58,13 @@ public function __construct( string $name, string $type, Table $table, + string $nameWithoutPrefix, Column $column, Table $referenceTable, Column $referenceColumn, string $onDelete ) { - parent::__construct($name, $type, $table); + parent::__construct($name, $type, $table, $nameWithoutPrefix); $this->column = $column; $this->referenceTable = $referenceTable; $this->referenceColumn = $referenceColumn; diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php index 030f2a49d81df..0e1ad0768c4da 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php @@ -5,7 +5,9 @@ */ namespace Magento\Framework\Setup\Declaration\Schema\Dto\Factories; +use Magento\Framework\App\ResourceConnection; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** * Foreign key constraint factory. @@ -27,18 +29,34 @@ class Foreign implements FactoryInterface */ private $className; + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var TableNameResolver + */ + private $tableNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager - * @param string $className + * @param ResourceConnection $resourceConnection + * @param TableNameResolver $tableNameResolver + * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, + ResourceConnection $resourceConnection, + TableNameResolver $tableNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Reference::class ) { $this->objectManager = $objectManager; + $this->resourceConnection = $resourceConnection; $this->className = $className; + $this->tableNameResolver = $tableNameResolver; } /** @@ -50,6 +68,23 @@ public function create(array $data) $data['onDelete'] = self::DEFAULT_ON_DELETE; } + $nameWithoutPrefix = $data['name']; + + if ($this->resourceConnection->getTablePrefix()) { + $nameWithoutPrefix = $this->resourceConnection + ->getConnection($data['table']->getResource()) + ->getForeignKeyName( + $this->tableNameResolver->getNameOfOriginTable( + $data['table']->getNameWithoutPrefix() + ), + $data['column']->getName(), + $data['referenceTable']->getNameWithoutPrefix(), + $data['referenceColumn']->getName() + ); + } + + $data['nameWithoutPrefix'] = $nameWithoutPrefix; + return $this->objectManager->create($this->className, $data); } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php index 919aa05634512..dd2acd7608867 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php @@ -5,7 +5,10 @@ */ namespace Magento\Framework\Setup\Declaration\Schema\Dto\Factories; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** * Index element factory. @@ -27,18 +30,34 @@ class Index implements FactoryInterface */ private $className; + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var TableNameResolver + */ + private $tableNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager - * @param string $className + * @param ResourceConnection $resourceConnection + * @param TableNameResolver $tableNameResolver + * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, + ResourceConnection $resourceConnection, + TableNameResolver $tableNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Index::class ) { $this->objectManager = $objectManager; + $this->resourceConnection = $resourceConnection; $this->className = $className; + $this->tableNameResolver = $tableNameResolver; } /** @@ -50,6 +69,30 @@ public function create(array $data) $data['indexType'] = self::DEFAULT_INDEX_TYPE; } + $nameWithoutPrefix = $data['name']; + + if ($this->resourceConnection->getTablePrefix()) { + /** + * Temporary solution. + * @see MAGETWO-91365 + */ + $indexType = AdapterInterface::INDEX_TYPE_INDEX; + if ($data['indexType'] === AdapterInterface::INDEX_TYPE_FULLTEXT) { + $indexType = $data['indexType']; + } + $nameWithoutPrefix = $this->resourceConnection + ->getConnection($data['table']->getResource()) + ->getIndexName( + $this->tableNameResolver->getNameOfOriginTable( + $data['table']->getNameWithoutPrefix() + ), + $data['column'], + $indexType + ); + } + + $data['nameWithoutPrefix'] = $nameWithoutPrefix; + return $this->objectManager->create($this->className, $data); } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Primary.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Primary.php index ca87ab34f007d..836e32efec057 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Primary.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Primary.php @@ -45,6 +45,7 @@ public function __construct( public function create(array $data) { $data['name'] = Internal::PRIMARY_NAME; + $data['nameWithoutPrefix'] = $data['name']; return $this->objectManager->create($this->className, $data); } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Table.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Table.php index 7c552acda5157..0a8f5b4ad23b3 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Table.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Table.php @@ -86,7 +86,7 @@ public function create(array $data) $tablePrefix = $this->resourceConnection->getTablePrefix(); $nameWithoutPrefix = $data['name']; if (!empty($tablePrefix) && strpos($nameWithoutPrefix, $tablePrefix) === 0) { - $data['nameWithoutPrefix'] = str_replace($tablePrefix, "", $data['name']); + $data['nameWithoutPrefix'] = preg_replace('/^' . $tablePrefix . '/i', '', $data['name']); } else { $data['name'] = $tablePrefix . $data['name']; $data['nameWithoutPrefix'] = $nameWithoutPrefix; diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php index 3709f035fe3a4..57e5270b0c82e 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php @@ -5,7 +5,9 @@ */ namespace Magento\Framework\Setup\Declaration\Schema\Dto\Factories; +use Magento\Framework\App\ResourceConnection; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** * Unique constraint DTO element factory. @@ -22,18 +24,34 @@ class Unique implements FactoryInterface */ private $className; + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var TableNameResolver + */ + private $tableNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager - * @param string $className + * @param ResourceConnection $resourceConnection + * @param TableNameResolver $tableNameResolver + * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, + ResourceConnection $resourceConnection, + TableNameResolver $tableNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Internal::class ) { $this->objectManager = $objectManager; + $this->resourceConnection = $resourceConnection; $this->className = $className; + $this->tableNameResolver = $tableNameResolver; } /** @@ -41,6 +59,22 @@ public function __construct( */ public function create(array $data) { + $nameWithoutPrefix = $data['name']; + + if ($this->resourceConnection->getTablePrefix()) { + $nameWithoutPrefix = $this->resourceConnection + ->getConnection($data['table']->getResource()) + ->getIndexName( + $this->tableNameResolver->getNameOfOriginTable( + $data['table']->getNameWithoutPrefix() + ), + $data['column'], + $data['type'] + ); + } + + $data['nameWithoutPrefix'] = $nameWithoutPrefix; + return $this->objectManager->create($this->className, $data); } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Index.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Index.php index ea8c07bf19e4c..49436adad04e8 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Index.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Index.php @@ -39,6 +39,11 @@ class Index extends GenericElement implements */ private $indexType; + /** + * @var string + */ + private $nameWithoutPrefix; + /** * Constructor. * @@ -47,18 +52,21 @@ class Index extends GenericElement implements * @param Table $table * @param array $columns * @param string $indexType + * @param string $nameWithoutPrefix */ public function __construct( string $name, string $type, Table $table, array $columns, - string $indexType + string $indexType, + string $nameWithoutPrefix ) { parent::__construct($name, $type); $this->table = $table; $this->columns = $columns; $this->indexType = $indexType; + $this->nameWithoutPrefix = $nameWithoutPrefix; } /** @@ -123,4 +131,14 @@ public function getIndexType() { return $this->indexType; } + + /** + * Retrieve the index name which is calculated without table prefix. + * + * @return string + */ + public function getNameWithoutPrefix() + { + return $this->nameWithoutPrefix; + } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php index 9cda6aa4a8842..9a42090ad31db 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php @@ -110,6 +110,7 @@ private function getTemporaryIndexHistory(Column $column) Index::TYPE, [ 'name' => self::TEMPORARY_KEY, + 'column' => $column->getName(), 'columns' => [$column], 'table' => $column->getTable() ] diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/TableNameResolver.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/TableNameResolver.php new file mode 100644 index 0000000000000..6cca87bd19b80 --- /dev/null +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/TableNameResolver.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Setup\Declaration\Schema; + +/** + * Resolver of table names. + */ +class TableNameResolver +{ + /** + * RegEx pattern is used to search cloned temporary tables used as a replica. + * + * @var string + */ + private $filterPattern = ''; + + /** + * Provides the name of the origin table for cloned tables. + * + * Replica tables should be identical to the original - + * indexes and constraints must use the original table name to calculate their own names. + * + * @param string $tableName + * @return string + */ + public function getNameOfOriginTable(string $tableName): string + { + $tableIsReplica = preg_match($this->getFilterPattern(), $tableName, $matches); + + return $tableIsReplica ? $matches['table_name'] : $tableName; + } + + /** + * Provides a RegEx pattern used to search cloned temporary tables used as a replica. + * + * @return string + */ + private function getFilterPattern(): string + { + if (!$this->filterPattern) { + $this->filterPattern = '#(?<table_name>\S+)_replica$#i'; + } + + return $this->filterPattern; + } +} diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd index 61540ecc616b0..8c264bd95a076 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd @@ -10,6 +10,6 @@ <xs:attributeGroup name="baseConstraint"> <xs:attributeGroup ref="basicOperations" /> - <xs:attribute name="name" type="nameType" /> + <xs:attribute name="name" type="nameType" use="required" /> </xs:attributeGroup> </xs:schema> diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php index 0a2eb60fda48a..15dfcc746407e 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php @@ -133,7 +133,8 @@ public function dataProvider() 'type' => 'primary', 'column' => [ 'first_column' - ] + ], + 'nameWithoutPrefix' => 'PRIMARY', ] ] ], @@ -141,9 +142,10 @@ public function dataProvider() 'second_table' => [ 'FIRST_INDEX' => [ 'name' => 'FIRST_INDEX', + 'nameWithoutPrefix' => 'FIRST_INDEX', 'column' => [ 'ref_column' - ] + ], ] ] ] @@ -221,6 +223,7 @@ private function createPrimaryConstraint(Table $table, array $columns) 'PRIMARY', 'primary', $table, + 'PRIMARY', $columns ); } @@ -240,7 +243,8 @@ private function createIndex($indexName, Table $table, array $columns) 'index', $table, $columns, - 'btree' + 'btree', + $indexName ); } @@ -370,6 +374,7 @@ private function prepareSchemaMocks(array $columns, array $references, array $co 'some_foreign_key', 'foreign', $table, + 'some_foreign_key', $foreignColumn, $refTable, $refColumn, @@ -429,6 +434,7 @@ private function prepareSchemaMocks(array $columns, array $references, array $co 'type' => 'primary', 'columns' => [$firstColumn], 'table' => $table, + 'nameWithoutPrefix' => 'PRIMARY', 'column' => ['first_column'], ] ], @@ -460,6 +466,7 @@ private function prepareSchemaMocks(array $columns, array $references, array $co 'table' => $refTable, 'column' => ['ref_column'], 'columns' => [$refColumn], + 'nameWithoutPrefix' => 'FIRST_INDEX', ] ], [ diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Declaration/SchemaBuilderTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Declaration/SchemaBuilderTest.php index f596a448f1aba..a590a50edb72f 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Declaration/SchemaBuilderTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Declaration/SchemaBuilderTest.php @@ -241,14 +241,16 @@ private function createIntegerColumn($name, Table $table) * * @param Table $table * @param array $columns + * @param string $nameWithoutPrefix * @return Internal */ - private function createPrimaryConstraint(Table $table, array $columns) + private function createPrimaryConstraint(Table $table, array $columns, $nameWithoutPrefix = 'PRIMARY') { return new Internal( 'PRIMARY', 'primary', $table, + $nameWithoutPrefix, $columns ); } @@ -259,16 +261,18 @@ private function createPrimaryConstraint(Table $table, array $columns) * @param string $indexName * @param Table $table * @param array $columns + * @param string|null $nameWithoutPrefix * @return Index */ - private function createIndex($indexName, Table $table, array $columns) + private function createIndex($indexName, Table $table, array $columns, $nameWithoutPrefix = null) { return new Index( $indexName, 'index', $table, $columns, - 'btree' + 'btree', + $nameWithoutPrefix ?: $indexName ); } @@ -295,13 +299,14 @@ private function createTimestampColumn($name, Table $table) * @dataProvider tablesProvider * @param array $tablesData * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @throws \Magento\Framework\Setup\Exception */ public function testBuild(array $tablesData) { $table = $this->createTable('first_table'); $refTable = $this->createTable('second_table'); $refColumn = $this->createIntegerColumn('ref_column', $refTable); - $index = $this->createIndex('FIRST_INDEX', $table, [$refColumn]); + $index = $this->createIndex('PRE_FIRST_INDEX', $table, [$refColumn], 'FIRST_INDEX'); $refTable->addColumns([$refColumn]); $refTable->addIndexes([$index]); $firstColumn = $this->createIntegerAIColumn('first_column', $table); @@ -312,6 +317,7 @@ public function testBuild(array $tablesData) 'some_foreign_key', 'foreign', $table, + 'some_foreign_key', $foreignColumn, $refTable, $refColumn, diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Diff/DiffManagerTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Diff/DiffManagerTest.php index 8a8aecb818348..22dc6c6d18a9e 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Diff/DiffManagerTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Diff/DiffManagerTest.php @@ -107,8 +107,8 @@ public function testRegisterIndexModification() '' ); $column = new Column('third', 'int', $table, 'Previous column'); - $index = new Index('index_type', 'index', $table, [$column], 'btree'); - $generatedIndex = new Index('index_type', 'index', $table, [$column], 'hash'); + $index = new Index('index_type', 'index', $table, [$column], 'btree', 'index_type'); + $generatedIndex = new Index('index_type', 'index', $table, [$column], 'hash', 'index_type'); $diff->expects(self::exactly(2)) ->method('register') ->withConsecutive([$generatedIndex, 'drop_element', $generatedIndex], [$index, 'add_complex_element']); @@ -142,7 +142,7 @@ public function testRegisterRemovalReference() '' ); $column = new Column('third', 'int', $table, 'Previous column'); - $reference = new Reference('ref', 'foreign', $table, $column, $refTable, $column, 'CASCADE'); + $reference = new Reference('ref', 'foreign', $table, 'ref', $column, $refTable, $column, 'CASCADE'); $diff->expects(self::exactly(2)) ->method('register') ->withConsecutive( @@ -169,7 +169,7 @@ public function testRegisterCreation() '' ); $column = new Column('third', 'int', $table, 'Previous column'); - $reference = new Reference('ref', 'foreign', $table, $column, $table, $column, 'CASCADE'); + $reference = new Reference('ref', 'foreign', $table, 'ref', $column, $table, $column, 'CASCADE'); $diff->expects(self::exactly(3)) ->method('register') ->withConsecutive( diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php new file mode 100644 index 0000000000000..ee4331e7bfc5b --- /dev/null +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php @@ -0,0 +1,187 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Setup\Test\Unit\Declaration\Schema\Dto\Factories; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DataObject; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Reference; +use Magento\Framework\Setup\Declaration\Schema\Dto\Factories\Foreign; +use Magento\Framework\Setup\Declaration\Schema\Dto\Table; +use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +/** + * Test foreign factory. + */ +class ForeignTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ObjectManagerHelper + */ + private $objectManagerHelper; + + /** + * @var ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $objectManagerMock; + + /** + * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject + */ + private $resourceConnectionMock; + + /** + * @var AdapterInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $adapterMock; + + /** + * @var TableNameResolver|\PHPUnit_Framework_MockObject_MockObject + */ + private $tableNameResolver; + + /** + * @var Foreign + */ + private $foreignFactory; + + public function setUp() + { + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->resourceConnectionMock = $this->getMockBuilder(ResourceConnection::class) + ->disableOriginalConstructor() + ->getMock(); + $this->adapterMock = $this->getMockBuilder(AdapterInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->tableNameResolver = $this->getMockBuilder(TableNameResolver::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->foreignFactory = $this->objectManagerHelper->getObject( + Foreign::class, + [ + 'objectManager' => $this->objectManagerMock, + 'resourceConnection' => $this->resourceConnectionMock, + 'tableNameResolver' => $this->tableNameResolver, + ] + ); + } + + /** + * @param string $prefix + * @dataProvider createDataProvider + */ + public function testCreate(string $prefix) + { + $resource = 'default'; + $tableNameWithoutPrefix = 'table_name'; + $tableName = $prefix . $tableNameWithoutPrefix; + + $columnName = 'entity_id'; + $referenceTableName = 'second_table'; + $referenceColumnName = 'website_id'; + + $foreignKeyNameWithoutPrefix = 'table_name_field_name'; + $foreignKeyName = $prefix . $foreignKeyNameWithoutPrefix; + + $table = $this->objectManagerHelper->getObject( + DataObject::class, + [ + 'data' => [ + 'resource' => $resource, + 'name' => $tableName, + 'name_without_prefix' => $tableNameWithoutPrefix, + ], + ] + ); + + $columnMock = $this->objectManagerHelper->getObject( + DataObject::class, + [ + 'data' => ['name' => $columnName], + ] + ); + + $referenceTableMock = $this->objectManagerHelper->getObject( + DataObject::class, + [ + 'data' => ['name_without_prefix' => $referenceTableName], + ] + ); + + $referenceColumnMock = $this->objectManagerHelper->getObject( + DataObject::class, + [ + 'data' => ['name' => $referenceColumnName], + ] + ); + + $data = [ + 'name' => $foreignKeyName, + 'table' => $table, + 'column' => $columnMock, + 'referenceTable' => $referenceTableMock, + 'referenceColumn' => $referenceColumnMock, + ]; + + $expectedData = array_merge( + $data, + [ + 'onDelete' => Foreign::DEFAULT_ON_DELETE, + 'nameWithoutPrefix' => $foreignKeyNameWithoutPrefix, + ] + ); + + $this->resourceConnectionMock + ->method('getTablePrefix') + ->willReturn($prefix); + + $this->resourceConnectionMock + ->method('getConnection') + ->with($resource) + ->willReturn($this->adapterMock); + + $this->tableNameResolver + ->method('getNameOfOriginTable') + ->with($tableNameWithoutPrefix) + ->willReturn($tableNameWithoutPrefix); + + $this->adapterMock + ->method('getForeignKeyName') + ->with($tableNameWithoutPrefix, $columnName, $referenceTableName, $referenceColumnName) + ->willReturn($foreignKeyNameWithoutPrefix); + + $this->objectManagerMock + ->expects($this->once()) + ->method('create') + ->with(Reference::class, $expectedData); + + $this->foreignFactory->create($data); + } + + /** + * @return array + */ + public function createDataProvider(): array + { + return [ + 'Prefix is defined' => [ + 'pref_', + ], + 'Prefix is not defined' => [ + '', + ], + ]; + } +} diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Operations/AddColumnTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Operations/AddColumnTest.php index d061fc1fb6c9c..a8a8fb5b0c40c 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Operations/AddColumnTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Operations/AddColumnTest.php @@ -179,7 +179,7 @@ public function testDoOperation() ->method('addElement') ->with('int', 'default', 'table', $definition, 'column') ->willReturn($statement); - $index = new Index('index', 'index', $column->getTable(), [$column], 'btree'); + $index = new Index('index', 'index', $column->getTable(), [$column], 'btree', 'index'); $this->elementFactoryMock->expects(self::once()) ->method('create') ->willReturn($index); diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/CheckReferenceColumnHasIndexTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/CheckReferenceColumnHasIndexTest.php index a0bf758004346..396cc2b2e5b34 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/CheckReferenceColumnHasIndexTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/CheckReferenceColumnHasIndexTest.php @@ -60,6 +60,7 @@ public function testValidate() 'ref', 'foreign', $table, + 'ref', $column, $refTable, $refColumn, diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/ValidationRulesTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/ValidationRulesTest.php index c4e88b569d9c2..ad547053f7bf2 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/ValidationRulesTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/ValidationRulesTest.php @@ -64,6 +64,7 @@ public function testValidate() 'ref', 'foreign', $table, + 'ref', $column, $refTable, $refColumn, diff --git a/lib/internal/Magento/Framework/Validator/Test/Unit/ConfigTest.php b/lib/internal/Magento/Framework/Validator/Test/Unit/ConfigTest.php index 213a71c0087ea..6717095376625 100644 --- a/lib/internal/Magento/Framework/Validator/Test/Unit/ConfigTest.php +++ b/lib/internal/Magento/Framework/Validator/Test/Unit/ConfigTest.php @@ -51,7 +51,7 @@ public function testConstructException() protected function _initConfig(array $files = null) { if (null === $files) { - $files = glob(__DIR__ . '/_files/validation/positive/*/validation.xml'); + $files = glob(__DIR__ . '/_files/validation/positive/*/validation.xml', GLOB_NOSORT); } $configFiles = []; foreach ($files as $path) { diff --git a/lib/internal/Magento/Framework/View/Template/Html/Minifier.php b/lib/internal/Magento/Framework/View/Template/Html/Minifier.php index 0e25331a1e687..796cc8bef0f28 100644 --- a/lib/internal/Magento/Framework/View/Template/Html/Minifier.php +++ b/lib/internal/Magento/Framework/View/Template/Html/Minifier.php @@ -131,8 +131,8 @@ public function minify($file) '#(?<!:|\\\\|\'|")//(?!\s*\<\!\[)(?!\s*]]\>)[^\n\r]*#', '', preg_replace( - '#(?<!:|\'|")//[^\n\r]*(\s\?\>)#', - '$1', + '#(?<!:|\'|")//[^\n\r]*(\?\>)#', + ' $1', preg_replace( '#(?<!:)//[^\n\r]*(\<\?php)[^\n\r]*(\s\?\>)[^\n\r]*#', '', diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Template/Html/MinifierTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Template/Html/MinifierTest.php index 53b7fe827376f..f07f7f4bdd8c1 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Template/Html/MinifierTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Template/Html/MinifierTest.php @@ -156,6 +156,11 @@ public function testMinify() <?php echo '//some.link.com/' ?> <em>inline text</em> <a href="http://www.<?php echo 'hi' ?>"></a> + <?php// if (\$block->getSomeVariable() > 1):?> + <?php echo \$block->getChildHtml('someChildBlock'); ?> + <?php //else:?> + <?php // echo \$block->getChildHtml('anotherChildBlock'); ?> + <?php // endif; ?> </body> </html> TEXT; @@ -179,7 +184,7 @@ public function testMinify() } }); //]]> -</script><?php echo "http://some.link.com/" ?> <?php echo "//some.link.com/" ?> <?php echo '//some.link.com/' ?> <em>inline text</em> <a href="http://www.<?php echo 'hi' ?>"></a></body></html> +</script><?php echo "http://some.link.com/" ?> <?php echo "//some.link.com/" ?> <?php echo '//some.link.com/' ?> <em>inline text</em> <a href="http://www.<?php echo 'hi' ?>"></a> <?php ?> <?php echo \$block->getChildHtml('someChildBlock'); ?> <?php ?> <?php ?> <?php ?></body></html> TEXT; $this->appDirectoryMock->expects($this->once()) diff --git a/lib/internal/Magento/Framework/Webapi/Rest/Response/FieldsFilter.php b/lib/internal/Magento/Framework/Webapi/Rest/Response/FieldsFilter.php index 9b50b45a9215c..87be46c111545 100644 --- a/lib/internal/Magento/Framework/Webapi/Rest/Response/FieldsFilter.php +++ b/lib/internal/Magento/Framework/Webapi/Rest/Response/FieldsFilter.php @@ -106,9 +106,9 @@ protected function parse($filterString) } switch ($filterString[$position]) { case '[': - array_push($parent, $currentElement); + $parent[] = $currentElement; // push current field in stack and initialize current - array_push($stack, $current); + $stack[] = $current; $current = []; break; diff --git a/lib/web/css/docs/source/_typography.less b/lib/web/css/docs/source/_typography.less index b360c672a6d7c..f6a355917ba8e 100644 --- a/lib/web/css/docs/source/_typography.less +++ b/lib/web/css/docs/source/_typography.less @@ -947,12 +947,8 @@ // ) { // @font-face { // font-family: @family-name; -// src: url('@{font-path}.eot'); -// src: url('@{font-path}.eot?#iefix') format('embedded-opentype'), -// url('@{font-path}.woff2') format('woff2'), -// url('@{font-path}.woff') format('woff'), -// url('@{font-path}.ttf') format('truetype'), -// url('@{font-path}.svg#@{family-name}') format('svg'); +// src: url('@{font-path}.woff2') format('woff2'), +// url('@{font-path}.woff') format('woff'); // font-weight: @font-weight; // font-style: @font-style; // } diff --git a/lib/web/css/source/lib/_buttons.less b/lib/web/css/source/lib/_buttons.less index 679c4b11fbaac..a92093b742902 100644 --- a/lib/web/css/source/lib/_buttons.less +++ b/lib/web/css/source/lib/_buttons.less @@ -276,6 +276,9 @@ // --------------------------------------------- .lib-button-primary( + @_button-font-family: @button-primary__font-family, + @_button-font-size: @button-primary__font-size, + @_button-font-weight: @button-primary__font-weight, @_button-line-height: @button-primary__line-height, @_button-width: @button-primary__width, @_button-margin: @button-primary__margin, @@ -299,6 +302,9 @@ @_button-gradient-direction: @button-primary__gradient-direction ) { .lib-button( + @_button-font-family: @_button-font-family, + @_button-font-size: @_button-font-size, + @_button-font-weight: @_button-font-weight, @_button-line-height: @_button-line-height, @_button-width: @_button-width, @_button-margin: @_button-margin, diff --git a/lib/web/css/source/lib/_navigation.less b/lib/web/css/source/lib/_navigation.less index 56aa2e7ef86b9..b2ed4352a334a 100644 --- a/lib/web/css/source/lib/_navigation.less +++ b/lib/web/css/source/lib/_navigation.less @@ -355,6 +355,25 @@ overflow: visible !important; } + &.parent { + > .level-top { + padding-right: 20px; + + > .ui-menu-icon { + position: absolute; + right: 0; + + .lib-icon-font( + @icon-down, + @_icon-font-size: 12px, + @_icon-font-line-height: 20px, + @_icon-font-text-hide: true, + @_icon-font-position: after + ); + } + } + } + .submenu { .lib-css(background, @_submenu-background-color); .lib-css(border, @_submenu-border-width @_submenu-border-style @_submenu-border-color); @@ -414,6 +433,26 @@ left: auto !important; right: 100%; } + + li { + margin: 0; + &.parent { + > a { + > .ui-menu-icon { + position: absolute; + right: 3px; + + .lib-icon-font( + @icon-next, + @_icon-font-size: 12px, + @_icon-font-line-height: 20px, + @_icon-font-text-hide: true, + @_icon-font-position: after + ); + } + } + } + } } &.more { diff --git a/lib/web/css/source/lib/_typography.less b/lib/web/css/source/lib/_typography.less index fae368b148e74..07128abbf7fcf 100644 --- a/lib/web/css/source/lib/_typography.less +++ b/lib/web/css/source/lib/_typography.less @@ -15,12 +15,8 @@ ) { @font-face { font-family: @family-name; - src: url('@{font-path}.eot'); - src: url('@{font-path}.eot?#iefix') format('embedded-opentype'), - url('@{font-path}.woff2') format('woff2'), - url('@{font-path}.woff') format('woff'), - url('@{font-path}.ttf') format('truetype'), - url('@{font-path}.svg#@{family-name}') format('svg'); + src: url('@{font-path}.woff2') format('woff2'), + url('@{font-path}.woff') format('woff'); font-weight: @font-weight; font-style: @font-style; } diff --git a/lib/web/css/source/lib/variables/_buttons.less b/lib/web/css/source/lib/variables/_buttons.less index 82f618faa1d0f..8c31c16143859 100644 --- a/lib/web/css/source/lib/variables/_buttons.less +++ b/lib/web/css/source/lib/variables/_buttons.less @@ -47,6 +47,9 @@ @button__active__gradient-color-end: false; // Primary button +@button-primary__font-family: @button__font-family; +@button-primary__font-size: @button__font-size; +@button-primary__font-weight: @button__font-weight; @button-primary__line-height: false; @button-primary__width: false; @button-primary__margin: false; diff --git a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot deleted file mode 100644 index 806461187aa48..0000000000000 Binary files a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot and /dev/null differ diff --git a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.svg b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.svg deleted file mode 100644 index 37d511d157533..0000000000000 --- a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg"><defs><font horiz-adv-x="1024"><font-face units-per-em="1024" ascent="960" descent="-64" /><missing-glyph horiz-adv-x="1024" /><glyph unicode=" " d="" horiz-adv-x="512" /><glyph unicode="" d="M676.571 637.696c-59.867 28.197-131.255 2.523-159.415-57.307-1.975-4.133-3.657-9.362-5.157-15.397-1.499 6.034-3.182 11.264-5.157 15.397-28.197 59.831-99.547 85.504-159.415 57.307-59.831-28.197-85.504-99.547-57.271-159.378 28.197-59.867 221.806-231.424 221.806-231.424s0 0.219 0.037 0.585c0.037-0.366 0.037-0.585 0.037-0.585s193.646 171.557 221.806 231.424c28.233 59.831 2.597 131.182-57.271 159.378z" /><glyph unicode="" d="M676.571 637.696c-59.831 28.197-131.218 2.523-159.451-57.307-1.938-4.133-3.657-9.362-5.157-15.397-1.463 6.034-3.182 11.264-5.157 15.397-28.16 59.831-99.547 85.504-159.378 57.307s-85.467-99.547-57.271-159.378 221.806-231.424 221.806-231.424 0 0.219 0.037 0.585c0-0.402 0-0.622 0-0.622s193.646 171.557 221.842 231.424c28.233 59.867 2.597 131.218-57.271 159.415zM690.213 479.232c-25.417-43.776-174.007-184.722-174.007-184.722l-1.573 2.999c0 0-155.465 140.398-181.211 183.991-30.61 51.822-7.753 108.946 38.949 128.439 43.52 18.176 101.888-27.319 123.502-73.143 1.499-3.182 17.627-1.463 18.798-6.107 1.134 4.645 12.727 2.926 14.226 6.107 21.577 45.824 81.042 93.989 128 72.411 46.007-21.138 66.926-72.155 33.317-129.975z" /><glyph unicode="" d="M512 704.11l-296.85-512.256h593.701l-296.85 512.256zM544.219 254.135h-62.757v49.92h62.757v-49.92zM528.713 343.369h-31.269l-20.809 140.654-1.207 72.704h72.521v-72.704l-19.237-140.654z" /><glyph unicode="" d="M628.846 588.544c-34.085 28.343-75.63 42.24-116.773 42.24-47.47 0-94.757-18.578-130.085-54.382l-32.073 29.586-0.585-102.693 110.994-0.658-39.424 41.253c25.198 24.027 58.002 36.315 91.136 36.352 29.842-0.037 59.721-9.947 84.517-30.574 31.488-26.222 47.689-63.744 47.726-101.815 0-5.449-0.366-10.971-1.024-16.457l51.383 9.874c0.073 2.231 0.146 4.425 0.146 6.619 0.037 52.37-22.491 104.521-65.938 140.654zM603.794 352.768c-25.307-24.466-58.405-37.010-91.867-37.047-29.879 0.037-59.721 9.984-84.517 30.574-31.488 26.222-47.689 63.744-47.726 101.778 0 6.327 0.475 12.617 1.353 18.871l-51.602-9.691c-0.146-3.072-0.256-6.107-0.256-9.179-0.037-52.334 22.491-104.521 65.975-140.617 34.048-28.343 75.593-42.24 116.736-42.24h0.11c47.799 0 95.378 18.907 130.743 55.223l33.938-33.829 0.219 106.094-112.055 0.293 38.949-40.229z" /><glyph unicode="" d="M696.942 624.933l-19.273 6.107h-74.496v38.583l-12.544 21.029-22.711 13.495h-111.141l-23.333-13.495-12.581-21.029v-38.619h-73.765l-18.761-6.656-17.189-14.153v-88.869h19.017v-0.073h17.554v-329.435h36.571v0.293h255.415v-0.293h36.571v329.435h18.286v0.073h18.286v86.601l-15.909 17.006zM457.435 667.575h109.129v-36.571h-109.129v36.571zM639.707 228.718h-255.415v292.571h255.415v-292.571zM676.279 557.934h-328.558v36.498h328.558v-36.498zM457.435 483.511h-36.571v-218.587h36.571v218.587zM530.578 483.511h-36.571v-218.587h36.571v218.587zM603.721 483.511h-36.571v-218.587h36.571v218.587z" /><glyph unicode="" d="M804.645 515.401c-1.499 4.681-5.888 7.899-10.789 7.899h-206.958l-64.073 196.754c-1.536 4.645-5.888 7.826-10.825 7.826-4.901 0-9.289-3.182-10.825-7.863l-64.439-196.754h-206.592c-4.901 0-9.289-3.218-10.825-7.863-1.499-4.681 0.146-9.874 4.096-12.763l167.205-121.783-64.439-197.851c-1.536-4.681 0.146-9.838 4.133-12.727 3.95-2.889 9.399-2.889 13.349 0l168.338 122.185 167.936-122.149c2.011-1.463 4.315-2.231 6.693-2.231s4.681 0.768 6.693 2.231c4.023 2.889 5.669 8.009 4.133 12.727l-64.439 197.851 167.57 121.783c3.95 2.889 5.632 8.046 4.059 12.727z" /><glyph unicode="" d="M807.241 415.854v67.145l-9.509 3.145-71.936 23.442-19.2 46.373 36.937 78.080-47.506 47.506-8.923-4.498-67.438-34.304-46.373 19.2-29.111 81.298h-67.182l-26.624-81.445-46.336-19.163-78.043 36.901-47.506-47.506 4.498-8.96 34.267-67.438-19.2-46.336-81.298-29.074v-67.218l9.472-3.072 71.973-23.515 19.163-46.373-36.901-78.080 47.506-47.506 8.887 4.498 67.474 34.304 46.373-19.2 29.111-81.298h67.182l3.072 9.509 23.515 71.936 46.373 19.2 78.080-36.937 47.506 47.506-4.498 8.923-34.304 67.438 19.2 46.373 81.298 29.147zM512 353.938c-51.968 0-94.062 42.13-94.062 94.062 0 52.005 42.094 94.062 94.062 94.062 51.931 0 94.098-42.057 94.098-94.062-0.037-51.931-42.167-94.062-94.098-94.062z" /><glyph unicode="" d="M339.602 539.941l172.398-183.881 172.398 183.881z" /><glyph unicode="" d="M606.939 449.938l-158.391 162.853-27.794-26.075 132.827-136.558-136.521-140.361 27.173-26.587 153.198 157.55-0.146 0.146z" /><glyph unicode="" d="M127.634 740.571v-73.143h768.731v73.143h-768.731zM127.634 411.429h768.731v73.143h-768.731v-73.143zM127.634 155.429h768.731v73.143h-768.731v-73.143z" /><glyph unicode="" d="M512 742.217c-102.437 0-185.417-83.054-185.417-185.454 0-102.437 185.417-403.017 185.417-403.017s185.454 300.581 185.454 403.017c-0.037 102.437-83.017 185.454-185.454 185.454zM512 500.443c-31.122 0-56.357 25.198-56.357 56.357 0 31.086 25.234 56.357 56.357 56.357 31.159 0 56.393-25.271 56.393-56.357-0.037-31.159-25.271-56.357-56.393-56.357z" /><glyph unicode="" d="M219.429 485.595h255.927v254.793h-255.927v-254.793zM548.571 740.389v-109.349h256v109.349h-256zM219.429 156.453h255.927v254.793h-255.927v-254.793zM548.571 484.754h256v109.349h-256v-109.349zM548.571 301.897h256v109.349h-256v-109.349zM548.571 155.611h256v109.349h-256v-109.349z" /><glyph unicode="" d="M579.511 677.010c-30.793 0-57.381-25.161-57.381-55.954 0-28.635 18.907-47.579 47.579-47.579 31.415 0 58.002 23.771 58.002 55.991 0 28.709-20.224 47.543-48.201 47.543zM593.518 336.494c-9.801 0-48.311-59.502-69.266-59.502-5.595 0-8.375 4.937-8.375 9.801 0 11.227 7.68 28.709 11.849 39.205l50.322 136.375c25.198 67.84-6.985 86.016-37.047 86.016-40.558 0-76.946-20.297-104.887-46.848-9.106-9.070-39.863-38.437-39.863-51.054 0-4.133 4.169-9.070 9.106-9.070 12.544 0 46.153 60.855 72.009 60.855 5.595 0 11.886-6.29 6.985-18.871l-48.896-123.173c-4.937-11.849-28.709-69.23-28.709-102.802 0-26.587 17.518-38.437 42.679-38.437 70.656 0 152.43 86.711 152.43 107.008 0 6.29-4.864 10.496-8.338 10.496z" /><glyph unicode="" d="M219.063 593.92h147.017v147.017h-147.017v-147.017zM438.491 593.92h147.017v147.017h-147.017v-147.017zM657.92 740.937v-147.017h147.017v147.017h-147.017zM219.063 374.491h147.017v147.017h-147.017v-147.017zM438.491 374.491h147.017v147.017h-147.017v-147.017zM657.92 374.491h147.017v147.017h-147.017v-147.017zM219.063 155.063h147.017v147.017h-147.017v-147.017zM438.491 155.063h147.017v147.017h-147.017v-147.017zM657.92 155.063h147.017v147.017h-147.017v-147.017z" /><glyph unicode="" d="M711.607 401.591l-5.486-5.522c21.065 27.794 32.878 60.197 32.219 94.72-1.975 99.218-106.679 177.627-233.874 175.141-127.232-2.487-228.791-84.992-226.816-184.21 1.938-99.182 106.679-177.554 233.911-175.067 28.635 0.585 50.432-5.815 75.63 2.121l159.232-78.702c-0.037-0.037-71.058 124.965-34.816 171.52z" /><glyph unicode="" d="M236.946 466.286h550.107v-36.571h-550.107v36.571z" /><glyph unicode="" d="M749.129 663.698c-152.101-93.257-262.473-210.907-312.064-269.934l-121.417 95.159-53.65-43.264 209.847-213.394c36.096 92.489 150.491 273.298 290.158 401.737l-12.873 29.696z" /><glyph unicode="" d="M434.871 259.95c-35.218 0-63.707-28.526-63.707-63.744 0-35.182 28.489-63.671 63.707-63.671 35.182 0 63.707 28.489 63.707 63.671 0 35.218-28.526 63.744-63.707 63.744zM654.848 259.95c-35.218 0-63.707-28.526-63.707-63.744 0-35.182 28.489-63.671 63.707-63.671 35.145 0 63.707 28.489 63.707 63.671 0 35.218-28.562 63.744-63.707 63.744zM784.274 616.741c-163.511 0-427.227 0-427.227 0s-25.929 70.071-49.957 113.371c-24.027 43.227-57.893 32.037-57.893 32.037-26.843 0-39.314-16.055-39.314-42.971 0-26.843 16.457-48.64 43.337-48.64l16.603-14.848 121.929-330.533 356.425-0.256c0 0 65.17 261.705 61.806 251.355 11.959 36.974-3.255 40.485-25.71 40.485zM392.485 492.544c-18.725 0-33.902 15.177-33.902 33.902s15.177 33.902 33.902 33.902 33.902-15.177 33.902-33.902-15.177-33.902-33.902-33.902zM464.933 379.392c-18.725 0-33.902 15.177-33.902 33.902s15.177 33.902 33.902 33.902 33.902-15.177 33.902-33.902-15.177-33.902-33.902-33.902zM502.199 492.544c-18.725 0-33.902 15.177-33.902 33.902s15.177 33.902 33.902 33.902 33.902-15.177 33.902-33.902-15.177-33.902-33.902-33.902zM574.647 379.392c-18.725 0-33.865 15.177-33.865 33.902s15.177 33.902 33.865 33.902 33.938-15.177 33.938-33.902-15.214-33.902-33.938-33.902zM611.913 492.544c-18.725 0-33.938 15.177-33.938 33.902s15.214 33.902 33.938 33.902 33.865-15.177 33.865-33.902-15.141-33.902-33.865-33.902zM684.361 379.392c-18.725 0-33.865 15.177-33.865 33.902s15.141 33.902 33.865 33.902 33.938-15.177 33.938-33.902-15.214-33.902-33.938-33.902zM721.627 492.544c-18.725 0-33.938 15.177-33.938 33.902s15.214 33.902 33.938 33.902 33.865-15.177 33.865-33.902-15.141-33.902-33.865-33.902z" /><glyph unicode="" d="M642.487 578.304c11.959 0 21.65 9.691 21.65 21.65v77.934c0 11.959-9.691 21.65-21.65 21.65-11.922 0-21.65-9.691-21.65-21.65v-77.934c0.037-11.959 9.728-21.65 21.65-21.65zM381.842 578.304c11.922 0 21.65 9.691 21.65 21.65v77.934c0 11.959-9.728 21.65-21.65 21.65-11.959 0-21.65-9.691-21.65-21.65v-77.934c0.037-11.959 9.691-21.65 21.65-21.65zM671.269 636.562v-0.402c8.997-7.973 14.702-19.566 14.702-32.549 0-23.991-19.456-43.447-43.483-43.447-23.991 0-43.447 19.456-43.447 43.447 0 12.946 5.705 24.576 14.702 32.549v0.402h-203.154v-0.402c8.997-7.973 14.702-19.566 14.702-32.549 0-23.991-19.456-43.447-43.447-43.447-24.027 0-43.447 19.456-43.447 43.447 0 12.946 5.669 24.576 14.665 32.549v0.402h-96.841v-440.101h511.561v440.101h-96.512zM732.087 234.569h-437.76v291.694h437.76v-291.694zM619.301 407.113h-55.15v-55.113h55.15v55.113zM619.301 490.021h-55.15v-55.113h55.15v55.113zM619.301 326.51h-55.15v-55.15h55.15v55.15zM696.942 490.021h-55.15v-55.113h55.15v55.113zM696.942 407.113h-55.15v-55.113h55.15v55.113zM386.267 326.51h-55.113v-55.15h55.113v55.15zM463.982 326.51h-55.15v-55.15h55.15v55.15zM463.982 407.113h-55.15v-55.113h55.15v55.113zM386.267 407.113h-55.113v-55.113h55.113v55.113zM541.586 407.113h-55.113v-55.113h55.113v55.113zM541.586 490.021h-55.113v-55.113h55.113v55.113zM463.982 490.021h-55.15v-55.113h55.15v55.113zM541.586 326.51h-55.113v-55.15h55.113v55.15z" /><glyph unicode="" d="M512 677.742l-209.006-253.257h136.338v-206.19h145.298v206.19h136.375z" /><glyph unicode="" d="M584.631 471.515v206.226h-145.298v-206.226h-136.338l209.006-253.221 209.006 253.221z" /><glyph unicode="" d="M836.462 183.918c0 0-109.641 112.677-153.381 156.233-19.054 19.017-32.073 31.927-32.073 31.927 14.848 21.211 26.405 44.361 34.633 69.339s12.361 51.237 12.361 78.848c0 35.621-6.802 69.083-20.334 100.462-13.568 31.305-32 58.697-55.406 82.030-23.369 23.442-50.725 41.874-82.066 55.406-31.305 13.605-64.768 20.37-100.389 20.37-35.584 0-69.047-6.802-100.425-20.37-31.305-13.531-58.551-31.963-81.664-55.406-23.077-23.296-41.435-50.688-54.967-81.993-13.568-31.378-20.334-64.841-20.334-100.462s6.802-69.083 20.334-100.389c13.531-31.305 31.89-58.661 54.967-82.103 23.113-23.333 50.322-41.801 81.664-55.369 31.378-13.568 64.841-20.297 100.425-20.297 27.648 0 53.943 4.023 78.885 12.288s48.091 19.858 69.303 34.706c0 0 11.922-11.959 29.696-29.806 48.421-48.603 155.026-159.159 155.026-159.159 16.018-6.985 41.728 0.439 54.455 11.337s19.858 33.682 9.289 52.407zM612.718 447.013c-9.838-22.747-23.223-42.569-40.155-59.429-16.933-16.933-36.718-30.354-59.429-40.192-22.638-9.874-46.848-14.775-72.521-14.775-26.258 0-50.688 4.937-73.362 14.775s-42.496 23.259-59.429 40.192c-16.896 16.859-30.354 36.681-40.155 59.429-9.838 22.601-14.738 47.104-14.738 73.289 0 25.673 4.901 50.030 14.738 72.997 9.838 22.93 23.259 42.898 40.155 59.794 16.933 16.969 36.754 30.354 59.429 40.155 22.674 9.911 47.104 14.738 73.362 14.738 25.673 0 49.883-4.864 72.521-14.738 22.674-9.801 42.496-23.186 59.429-40.155 16.933-16.933 30.318-36.901 40.155-59.831 9.874-22.967 14.738-47.323 14.738-72.997 0-26.149-4.901-50.651-14.738-73.253z" /><glyph unicode="" d="M695.845 602.661l-29.147 29.111-154.697-154.734-154.734 154.734-29.111-29.111 154.734-154.734-154.624-154.624 29.111-29.074 154.624 154.587 154.661-154.587 29.038 29.074-154.587 154.624z" /><glyph unicode="" d="M470.418 450.158l132.791 136.558-27.794 26.075-158.354-162.853 9.618-9.033-0.11-0.146 153.234-157.55 27.136 26.587z" /><glyph unicode="" d="M512 539.941l-172.398-183.881h344.795z" /><glyph unicode="" d="M392.119 622.043v-348.087l239.726 174.043z" /><glyph unicode="" d="M392.119 448l239.726-174.043v348.087z" /><glyph unicode="" d="M237.714 191.159h73.728v513.682h-73.728v-513.682zM786.286 703.086h-440.283v-292.169h440.283l-148.078 144.128 148.078 148.041z" /><glyph unicode="" d="M787.054 466.359h-256.219v256.695h-36.571v-256.695h-257.317v-36.571h257.317v-256.841h36.571v256.841h256.219z" /><glyph unicode="" d="M769.134 594.286v36.571h-513.17v-25.271l-1.097-1.097 1.097-1.097v-9.106h0.622v-292.571h-0.622v-8.558l-1.097-1.097 1.097-1.097v-25.819h513.17v36.571h-0.585v292.571h0.585zM703.89 301.714h-387.657l119.881 119.881-25.856 25.856-117.138-117.138v236.361l220.014-217.088 25.856 25.856-1.39 1.353 194.377 194.341v-245.87l-122.149 122.149-25.856-25.856 119.918-119.845zM317.221 594.286h386.158l-191.781-191.781-194.377 191.781z" /><glyph unicode="" d="M310.747 210.359h109.166v328.485h-109.166v-328.485zM604.050 355.584v-145.225h109.202v145.225h-109.202zM457.399 210.359h109.202v475.319h-109.202v-475.319z" /><glyph unicode="" d="M310.747 210.359h109.166v328.485h-109.166v-328.485zM347.941 503.625h36.864v-256.768h-36.864v256.768zM604.050 355.584v-145.225h109.202v145.225h-109.202zM677.339 246.711h-36.827v71.863h36.827v-71.863zM457.399 210.359h109.202v475.319h-109.202v-475.319zM494.263 649.838h36.827v-402.834h-36.827v402.834z" /><glyph unicode="" d="M519.57 665.893c-127.232 2.487-231.936-75.922-233.911-175.141-0.695-34.487 11.154-66.926 32.219-94.72l-5.486 5.522c36.242-46.519-34.816-171.52-34.816-171.52l159.232 78.702c25.161-7.936 46.994-1.536 75.63-2.121 127.232-2.487 231.973 75.886 233.911 175.067 2.011 99.255-99.511 181.723-226.779 184.21z" /><glyph unicode="" d="M514.158 489.582l136.558-132.791 26.075 27.794-162.853 158.354-166.729-162.743 26.587-27.136z" /><glyph unicode="" d="M509.842 406.418l-136.558 132.791-26.075-27.794 162.853-158.354 166.729 162.743-26.587 27.136z" /><glyph unicode="" d="M512 52.005c-218.77 0-396.032 177.298-396.032 395.995s177.262 395.995 396.032 395.995c218.661 0 396.032-177.298 396.032-395.995s-177.371-395.995-396.032-395.995zM512 796.087c-191.89 0-348.087-156.197-348.087-348.087 0-191.927 156.197-348.087 348.087-348.087s348.050 156.16 348.050 348.087c-0.037 191.927-156.16 348.087-348.050 348.087zM611.328 442.441l-24.101-18.761c-13.166-10.24-21.87-22.126-26.185-35.84-2.743-8.558-4.681-18.907-4.901-37.12h-92.343c1.353 38.473 5.413 61.842 11.301 76.581 5.925 14.592 21.102 31.488 45.531 50.578l24.795 19.383c8.192 6.181 14.738 12.91 19.785 20.187 8.997 12.471 13.495 26.222 13.495 41.216 0 17.262-5.010 32.987-15.104 47.214-10.057 14.226-28.453 21.321-55.259 21.321-26.295 0-44.946-8.777-55.918-26.295s-16.384-33.463-16.384-52.37h-98.523c2.706 64.805 25.234 108.544 67.73 135.57 26.843 17.298 59.794 25.929 98.889 25.929 51.383 0 94.025-12.288 128-36.827 34.011-24.503 53.87-74.935 53.87-123.173 0-29.55-10.24-40.338-25.051-60.599-8.558-12.288-25.125-27.941-49.627-46.994zM561.042 202.423h-98.231v98.487h98.231v-98.487z" /><glyph unicode="" d="M1.994 518.75h748.928l-283.278 291.206h200.254l354.108-363.956-354.108-363.956h-200.254l283.278 291.174h-748.928v145.532z" /><glyph unicode="" d="M1022.006 375.25h-748.928l283.278-291.206h-200.254l-354.108 363.956 354.108 363.956h200.254l-283.278-291.174h748.928v-145.532z" /><glyph unicode="" d="M85.174 468.026l0.504-106.238 426.322-426.324 426.32 426.324 0.504 106.238-389.444-389.444 0.002 880.006h-74.764v-880.004z" /><glyph unicode="" d="M511.963 831.086c-211.529 0-383.049-171.52-383.049-383.086s171.483-383.086 383.049-383.086c211.602 0 383.086 171.483 383.086 383.086s-171.483 383.086-383.086 383.086zM511.963 794.514c191.086 0 346.514-155.429 346.514-346.514 0-79.909-27.429-153.344-73.070-212.041-5.486 1.975-11.008 3.84-16.274 6.107-34.926 14.629-73.801 31.781-108.654 46.153-9.911 2.706-19.931 5.413-29.842 8.155-11.849 8.155-23.589 35.365-29.915 48.933-6.29 0.914-12.654 1.792-19.017 2.633 0.914 20.992 13.934 22.126 19.017 38.071 4.498 14.080 0.512 32.439 7.57 45.495 4.937 9.070 16.128 9.070 21.65 16.933 5.083 6.985 8.411 19.273 9.984 27.941 2.853 15.799 5.339 37.339-2.158 53.029-4.279 8.96-6.985 9.874-8.229 20.736-1.426 13.275 3.913 56.43 4.133 65.755 0.512 24.21-0.073 26.149-5.925 49.737 0 0-7.058 21.358-18.213 27.831l-22.272 3.803-13.714 12.727c-55.369 34.085-114.761 10.167-146.505-2.67-45.824-14.885-74.789-59.758-54.565-155.538 3.474-16.421-8.96-23.698-8.155-32.658 1.829-19.566 2.158-66.487 20.59-78.080 1.719-1.061 14.811-4.352 14.738-3.438 1.792-19.017 3.621-38.071 5.376-57.015 4.608-12.654 15.689-14.080 18.907-31.927l-14.153-3.438c-6.363-13.568-17.993-40.777-29.879-48.933-9.947-2.706-19.931-5.413-29.879-8.155-34.889-14.373-73.691-31.488-108.654-46.153-1.902-0.768-3.877-1.39-5.815-2.158-43.776 58.112-70.071 130.011-70.071 208.165 0 191.086 155.429 346.514 346.478 346.514z" /><glyph unicode="" d="M427.703 653.019c0-10.569-8.558-19.090-19.090-19.090h-11.154c-10.533 0-19.090 8.521-19.090 19.090v68.462c0 10.533 8.594 19.090 19.090 19.090h11.154c10.533 0 19.090-8.558 19.090-19.090v-68.462zM645.778 653.019c0-10.569-8.521-19.090-19.054-19.090h-11.154c-10.533 0-19.054 8.521-19.054 19.090v68.462c-0.037 10.533 8.485 19.090 19.054 19.090h11.154c10.533 0 19.054-8.558 19.054-19.090v-68.462zM675.182 481.317l-38.729 31.598-152.795-187.282-81.518 64.805-28.891-36.242 120.21-95.634zM758.784 687.982h-71.351v-29.769c0-31.634-25.746-57.344-57.271-57.344h-11.227c-31.598 0-57.271 25.71-57.271 57.344v29.769h-97.682v-29.769c0-31.634-25.71-57.344-57.307-57.344h-11.154c-31.598 0-57.307 25.71-57.307 57.344v29.769h-72.96c-10.533 0-19.090-8.521-19.090-19.054v-494.373c-0.037-10.569 8.558-19.127 19.090-19.127h493.531c10.533 0 19.054 8.558 19.054 19.090v494.409c0 10.533-8.521 19.054-19.054 19.054zM720.567 240.677c0-10.569-8.558-19.090-19.090-19.090h-378.917c-10.569 0-19.090 8.521-19.090 19.090v288.11c0 10.569 8.521 19.054 19.090 19.054h378.88c10.533 0 19.090-8.485 19.090-19.054v-288.11z" /><glyph unicode="" d="M391.863 554.203h-128.219c-10.35 0-18.761-8.375-18.761-18.725v-91.429c0-10.35 8.375-18.725 18.761-18.725h128.219c10.35 0 18.761 8.375 18.761 18.725v91.429c0 10.386-8.375 18.725-18.761 18.725zM391.863 387.511h-90.734c-10.35 0-18.761-8.375-18.761-18.725v-194.633c0-10.35 8.411-18.725 18.761-18.725h90.734c10.35 0 18.761 8.375 18.761 18.725v194.633c0 10.35-8.375 18.725-18.761 18.725zM760.357 554.203h-279.845c-10.35 0-18.725-8.375-18.725-18.725v-91.429c0-10.35 8.375-18.725 18.725-18.725h279.845c10.313 0 18.725 8.375 18.725 18.725v91.429c-0.037 10.386-8.411 18.725-18.725 18.725zM721.701 385.573h-240.64c-10.313 0-18.725-8.375-18.725-18.761v-192.695c0-10.35 8.375-18.725 18.725-18.725h240.64c10.35 0 18.725 8.375 18.725 18.725v192.695c0 10.35-8.375 18.761-18.725 18.761zM507.355 575.634c21.87-3.986 42.971-6.327 62.647-6.327 99.072 0 152.832 53.248 153.088 103.387 0.183 32.293-23.698 67.291-78.117 67.84-72.923 0-118.089-51.493-141.605-89.71-23.918 38.107-69.266 88.576-142.373 88.576-52.882-0.549-76.763-35.547-76.581-67.84 0.256-50.139 54.016-103.424 153.088-103.424 0.037 0 0.037 0 0.037 0 21.394 0 44.398 2.414 68.425 7.241l1.39 0.256zM645.998 693.723c9.143-0.073 30.354-2.304 30.245-20.773-0.11-23.589-33.17-56.795-106.24-56.795-10.057 0-20.553 0.658-31.525 1.938 16.567 29.294 51.566 75.63 107.52 75.63zM437.504 614.985v0c-73.106 0-106.167 33.207-106.277 56.795-0.11 18.469 21.102 20.699 31.305 20.809 55.259 0 90.039-46.373 106.496-75.666-10.935-1.28-21.467-1.938-31.525-1.938z" /><glyph unicode="" d="M938.824 426.028l-0.504 106.238-426.32 426.322-426.322-426.322-0.504-106.238 389.444 389.442v-880.006h74.764v880.006z" /></font></defs></svg> \ No newline at end of file diff --git a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.ttf b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.ttf deleted file mode 100644 index 6fabe5c3e8994..0000000000000 Binary files a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.ttf and /dev/null differ diff --git a/lib/web/fonts/MUI-Icons/MUI-Icons.eot b/lib/web/fonts/MUI-Icons/MUI-Icons.eot deleted file mode 100644 index 47cc307843c7f..0000000000000 Binary files a/lib/web/fonts/MUI-Icons/MUI-Icons.eot and /dev/null differ diff --git a/lib/web/fonts/MUI-Icons/MUI-Icons.svg b/lib/web/fonts/MUI-Icons/MUI-Icons.svg deleted file mode 100644 index dddb55583c550..0000000000000 --- a/lib/web/fonts/MUI-Icons/MUI-Icons.svg +++ /dev/null @@ -1,706 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > -<svg xmlns="http://www.w3.org/2000/svg"> -<metadata> -This is a custom SVG font generated by IcoMoon. -<iconset grid="16"></iconset> -</metadata> -<defs> -<font id="MUI-Icons" horiz-adv-x="512" > -<font-face units-per-em="512" ascent="480" descent="-32" /> -<missing-glyph horiz-adv-x="512" /> -<glyph unicode="" d="M 470.70,72.193l-2.688,2.688l 0.006,0.002L 360.505,182.408c 14.938,25.732, 23.612,55.564, 23.816,87.451 - c 0.626,97.615-77.986,177.243-175.599,177.857c-0.394,0.001-0.771,0.002-1.168,0.002 - c-97.06-0.006-176.063-78.391-176.688-175.598c-0.618-97.609, 77.999-177.236, 175.597-177.859 - c 0.389-0.002, 0.766-0.004, 1.155-0.004c 32.438,0.00, 62.846,8.79, 88.998,24.075l 107.415-107.433l 0.014,0.01l 2.688-2.688 - c 8.125-8.123, 21.293-8.114, 29.41,0.00l 34.562,34.557C 478.819,50.895, 478.822,64.07, 470.70,72.193z M 300.39,177.58 - c-24.834-24.67-57.78-38.252-92.768-38.252l-0.874,0.00 c-72.589,0.467-131.271,59.908-130.813,132.503 - c 0.465,72.128, 59.516,130.811, 131.626,130.815l 0.879-0.002c 35.168-0.22, 68.146-14.123, 92.852-39.148 - c 24.706-25.025, 38.188-58.178, 37.966-93.352C 339.031,235.128, 325.229,202.25, 300.39,177.58zM 223.902,351.597L 192.104,351.597L 192.104,287.997L 128.503,287.997L 128.503,256.203L 192.104,256.203L 192.104,192.604L 223.902,192.604L 223.902,256.203L 287.501,256.203L 287.501,287.997L 223.902,287.997 z" /> -<glyph unicode="" d="M 466.996,351.685c-3.893,12.271-9.538,21.313-21.31,21.313c0.00,0.00-80.181,11.00-189.351,11.00c-109.169,0.00-188.677-11.00-188.677-11.00 - c-11.77,0.00-16.889-8.316-21.313-21.313c0.00,0.00-13.67-31.687-13.67-127.685s 13.67-131.685, 13.67-131.685 - c 5.282-11.107, 9.543-21.313, 21.313-21.313c0.00,0.00, 92.343-7.00, 188.34-7.00s 189.688,9.00, 189.688,9.00c 11.771,0.00, 18.218,10.248, 21.31,21.313 - c0.00,0.00, 13.00,49.185, 13.00,129.185S 466.996,351.685, 466.996,351.685z M 192.002,134.882L 192.002,313.118 L 346.358,224.00L 192.002,134.882z" /> -<glyph unicode="" d="M 259.559,206.271L 198.73,29.528c 18.165-5.344, 37.372-8.263, 57.27-8.263c 23.607,0.00, 46.25,4.077, 67.32,11.492 - c-0.539,0.868-1.039,1.793-1.451,2.795L 259.559,206.271z M 392.855,234.231c0.00,25.062-9.006,42.404-16.719,55.904 - c-10.273,16.708-19.912,30.844-19.912,47.551c0.00,18.63, 14.131,35.979, 34.045,35.979c 0.896,0.00, 1.754-0.108, 2.625-0.165 - c-36.064,33.048-84.119,53.225-136.896,53.225c-70.82,0.00-133.128-36.34-169.375-91.37c 4.757-0.153, 9.241-0.244, 13.044-0.244 - c 21.196,0.00, 54.027,2.576, 54.027,2.576c 10.929,0.639, 12.213-15.416, 1.30-16.707c0.00,0.00-10.985-1.282-23.198-1.929l 73.815-219.589 - l 44.372,133.051l-31.584,86.541c-10.92,0.645-21.262,1.926-21.262,1.926c-10.927,0.646-9.646,17.347, 1.288,16.707 - c0.00,0.00, 33.47-2.576, 53.39-2.576c 21.199,0.00, 54.031,2.576, 54.031,2.576c 10.93,0.64, 12.217-15.414, 1.297-16.707 - c0.00,0.00-11.00-1.281-23.203-1.926l 73.262-217.916l 20.23,67.559C 386.182,196.747, 392.855,216.881, 392.855,234.231z M 357.918,48.78 - c 60.27,35.14, 100.803,100.438, 100.803,175.227c0.00,35.246-9.004,68.381-24.83,97.254c 0.871-6.455, 1.365-13.382, 1.365-20.847 - c0.00-20.563-3.854-43.688-15.416-72.608L 357.918,48.78z M 53.28,224.007c0.00-80.24, 46.624-149.592, 114.259-182.448l-96.705,264.95 - C 59.581,281.298, 53.28,253.397, 53.28,224.007z M 255.996-19.985c-134.53,0.00-243.98,109.457-243.98,243.993 - c0.00,134.527, 109.448,243.978, 243.98,243.978c 134.528,0.00, 243.988-109.449, 243.988-243.978 - C 499.986,89.472, 390.526-19.985, 255.996-19.985z" /> -<glyph unicode="" d="M 511.998,192.10L 224.002,192.10L 224.002,7.489L 511.998-32.01 - zM 192.002,192.10L-0.012,192.10L-0.012,39.671L 192.002,10.416 - zM 192.002,406.668L-0.012,377.284L-0.012,223.598L 192.002,223.598 - zM 511.998,223.598L 511.998,447.50L 224.002,409.463L 224.002,223.598 - z" /> -<glyph unicode="" d="M 206.569,224.042c-23.637,12.147-46.615,18.31-68.313,18.31c-2.951,0.00-5.921-0.088-8.892-0.35 - c-27.686-2.292-52.974-9.595-69.239-15.273c-4.314-1.584-8.736-3.258-13.292-5.106L 2.331,67.344 - c 30.569,11.313, 57.616,16.814, 82.378,16.814c 40.054,0.00, 69.128-14.966, 93.14-30.373c 11.376,38.604, 38.667,131.833, 46.812,159.694 - C 218.738,217.089, 212.731,220.697, 206.569,224.042z M 264.10,184.824l-44.812-155.644c 13.294-7.615, 58.017-31.732, 92.259-31.732 - c 27.641,0.00, 58.588,7.082, 94.547,21.695l 42.786,149.614c-29.05-9.375-56.915-14.131-82.97-14.131 - C 318.371,154.627, 285.096,170.035, 264.10,184.824z M 147.409,294.954c 38.208-0.396, 66.464-14.967, 89.882-29.976l 45.954,157.227 - c-9.685,5.547-35.081,19.369-53.438,24.079c-12.082,2.816-24.782,4.269-38.251,4.269c-25.663-0.483-53.701-6.909-85.657-19.719 - L 62.082,276.949c 32.109,12.107, 59.773,18.005, 85.259,18.005C 147.364,294.954, 147.409,294.954, 147.409,294.954z M 509.669,379.509 - c-29.14-11.313-57.575-17.076-84.735-17.076c-45.426,0.00-78.922,15.756-100.623,30.899l-45.556-157.67 - c 30.592-19.672, 63.561-29.666, 98.158-29.666c 28.215,0.00, 57.442,6.776, 86.933,20.158l-0.091,1.102l 1.851,0.438L 509.669,379.509z" /> -<glyph unicode="" d="M 497.573,54.108L 268.433,440.634c-2.945,5.237-8.634,8.138-14.595,7.183c-4.403-0.699-8.153-3.409-10.269-7.183 - L 14.429,54.108c-2.514-4.467-2.518-10.199,0.00-14.646c 2.553-4.506, 7.277-7.46, 12.423-7.46l 458.294,0.00 - c 5.135,0.00, 9.876,2.954, 12.428,7.46C 500.087,43.909, 500.087,49.642, 497.573,54.108z M 61.171,64.149L 256.00,395.105 - l 194.557-330.956L 61.171,64.149 zM 257.251,138.854c-13.655,0.00-24.724-11.319-24.724-25.289c0.00-13.971, 11.068-25.29, 24.724-25.29 - s 24.724,11.319, 24.724,25.29C 281.975,127.535, 270.906,138.854, 257.251,138.854zM 239.835,160.002L 272.693,160.002L 279.811,319.998L 232.729,319.998 z" /> -<glyph unicode="" d="M 428.26,271.336c-17.425,0.00-164.791,0.00-164.791,0.00s 12.625,48.421, 17.183,81.404 - c 4.653,33.547-5.064,60.663-5.064,60.663s-16.546,42.303-21.052,44.116c-27.224,10.979-41.333-4.307-41.333-4.307 - s0.00-62.789,0.00-71.317c0.00-7.919-1.445-13.601-1.445-13.601s-68.23-106.349-76.179-114.113 - c-7.955-7.778-39.428-22.117-39.428-22.117s0.00-175.948,0.00-192.961c 1.949-3.057, 33.037,1.104, 33.831-5.85 - c 0.788-6.943, 35.429-33.252, 35.429-33.252s 163.579,0.00, 181.953,0.00s 49.90,8.939, 54.987,20.781 - c 8.712,20.289-2.082,33.68-1.728,39.291c 0.357,5.609, 27.639,9.498, 27.639,33.52c 3.612,29.285-14.391,27.271-13.421,34.07 - c 0.98,6.801, 22.257,9.203, 26.379,24.717c 3.155,11.947, 5.866,34.635-12.967,44.708 - C 490.329,218.555, 458.143,271.336, 428.26,271.336z" /> -<glyph unicode="" d="M 428.26,250.91c 18.83,10.072, 16.122,32.761, 12.968,44.708c-4.123,15.515-25.402,17.917-26.38,24.717 - c-0.973,6.799, 17.033,4.783, 13.421,34.069c0.00,24.023-27.281,27.912-27.636,33.521c-0.354,5.609, 10.437,19.003, 1.725,39.29 - c-5.087,11.844-36.612,20.782-54.987,20.782c-18.374,0.00-181.953,0.00-181.953,0.00s-34.638-26.308-35.429-33.25 - c-0.794-6.955-31.882-2.792-33.831-5.85c0.00-17.015,0.00-192.964,0.00-192.964s 31.474-14.338, 39.428-22.117 - c 7.948-7.764, 76.183-114.111, 76.183-114.111s 1.441-5.684, 1.441-13.60c0.00-8.529,0.00-71.318,0.00-71.318 - s 14.109-15.285, 41.333-4.309c 4.508,1.814, 21.053,44.117, 21.053,44.117s 9.718,27.115, 5.067,60.66 - c-4.559,32.984-17.187,81.404-17.187,81.404s 147.366,0.00, 164.792,0.00C 458.143,176.662, 490.329,229.444, 428.26,250.91z" /> -<glyph unicode="" d="M 479.194,328.27c-25.192-141.915-165.958-262.095-208.297-289.552c-42.348-27.455-80.973,10.994-94.983,40.054 - c-16.035,33.166-64.104,212.868-76.683,227.765c-12.585,14.866-50.354-14.896-50.354-14.896L 30.56,315.658 - c0.00,0.00, 76.695,91.58, 135.047,103.026c 61.872,12.141, 61.781-95.006, 76.663-154.485c 14.389-57.542, 24.063-90.471, 36.626-90.471 - c 12.591,0.00, 36.636,32.096, 62.947,81.286c 26.363,49.242-1.139,92.74-52.649,61.791C 309.804,440.436, 504.375,470.161, 479.194,328.27z" /> -<glyph unicode="" d="M 352.264,277.059l0.00-106.112 L 480.00,95.498L 480.00,351.497 L 352.264,277.059z M 299.569,351.497L 53.988,351.497 - c-11.77,0.00-21.313-9.542-21.313-21.313l0.00-212.869 c0.00-11.771, 9.543-21.313, 21.313-21.313l 245.581,0.00 - c 11.771,0.00, 21.31,9.537, 21.31,21.313L 320.879,330.184 C 320.876,341.955, 311.341,351.497, 299.569,351.497" /> -<glyph unicode="" d="M 412.316,125.949c-20.918,8.813-76.904,30.871-82.859,32.495c-7.107,4.888-14.07,21.151-17.877,29.236 - c-3.789,0.544-7.574,1.087-11.377,1.624c 0.586,12.514, 8.334,13.182, 11.377,22.742c 2.676,8.432, 0.279,19.387, 4.527,27.197 - c 2.945,5.422, 9.617,5.457, 12.949,10.104c 3.02,4.216, 5.016,11.567, 5.955,16.732c 1.715,9.441, 3.217,22.354-1.268,31.716 - c-2.57,5.38-4.199,5.897-4.918,12.426c-0.867,7.914, 2.332,33.72, 2.467,39.30c 0.326,14.477-0.025,15.654-3.527,29.754 - c0.00,0.00-4.254,12.773-10.924,16.631L 303.547,398.20l-8.217,7.615c-33.106,20.365-68.602,6.081-87.613-1.623 - c-27.389-8.893-44.709-35.711-32.618-93.018c 2.063-9.789-5.361-14.164-4.877-19.502c 1.062-11.678, 1.287-39.758, 12.322-46.672 - c 1.024-0.642, 8.854-2.605, 8.803-2.068c 1.085-11.375, 2.167-22.754, 3.247-34.125c 2.756-7.553, 9.366-8.383, 11.288-19.063 - l-8.459-2.063c-3.802-8.085-10.771-24.341-17.876-29.236c-5.955-1.624-61.941-23.683-82.861-32.495 - c-19.05-8.036-34.543-21.347-34.543-47.359c0.00-26.015-0.388-29.216-0.058-45.959l 384.914-0.918 - c0.00,17.815, 0.059,33.315, 0.059,46.877C 447.057,102.137, 431.367,117.913, 412.316,125.949zM 493.723,177.562c-11.002,4.635-40.446,16.237-43.581,17.091c-3.737,2.57-7.399,11.124-9.401,15.376 - c-1.993,0.286-3.983,0.572-5.983,0.854c 0.307,6.581, 4.383,6.934, 5.983,11.961c 1.407,4.434, 0.147,10.197, 2.382,14.305 - c 1.55,2.852, 5.058,2.87, 6.812,5.314c 1.587,2.218, 2.638,6.084, 3.131,8.80c 0.901,4.966, 1.691,11.758-0.667,16.682 - c-1.353,2.829-2.208,3.101-2.585,6.535c-0.459,4.163, 1.225,17.735, 1.297,20.67c 0.171,7.615-0.013,8.233-1.856,15.649 - c0.00,0.00-2.236,6.718-5.746,8.748l-6.99,1.206l-4.322,4.005c-17.412,10.711-36.081,3.198-46.081-0.854 - c-14.404-4.677-23.515-18.782-17.154-48.923c 1.085-5.148-2.82-7.45-2.566-10.257c 0.559-6.143, 0.676-20.912, 6.481-24.548 - c 0.538-0.337, 4.655-1.37, 4.629-1.087c 0.571-5.983, 1.14-11.967, 1.708-17.947c 1.449-3.973, 4.927-4.409, 5.938-10.027l-4.448-1.085 - c-2.00-4.252-5.665-12.802-9.402-15.376c-1.837-0.501-12.729-4.70-23.643-9.022c-2.173-0.861, 2.669-8.846, 14.237-12.501 - c 40.043-12.647, 94.992-44.956, 94.992-44.956l 55.079-0.176c0.00,9.37, 0.032,17.522, 0.032,24.655 - C 511.996,165.037, 503.744,173.335, 493.723,177.562zM 18.275,177.562c 11.002,4.635, 40.447,16.237, 43.581,17.091c 3.738,2.57, 7.40,11.124, 9.402,15.376 - c 1.993,0.286, 3.983,0.572, 5.983,0.854c-0.307,6.581-4.383,6.934-5.983,11.961c-1.407,4.434-0.147,10.197-2.382,14.305 - c-1.549,2.852-5.058,2.87-6.811,5.314c-1.588,2.218-2.639,6.084-3.132,8.80c-0.902,4.966-1.691,11.758, 0.667,16.682 - c 1.353,2.829, 2.209,3.101, 2.586,6.535c 0.458,4.163-1.227,17.735-1.297,20.67c-0.171,7.615, 0.013,8.233, 1.856,15.649 - c0.00,0.00, 2.237,6.718, 5.746,8.748l 6.992,1.206l 4.321,4.005c 17.413,10.711, 36.082,3.198, 46.081-0.854 - c 14.405-4.677, 23.515-18.782, 17.155-48.923c-1.085-5.148, 2.82-7.45, 2.565-10.257c-0.559-6.143-0.676-20.912-6.48-24.548 - c-0.539-0.337-4.657-1.37-4.63-1.087c-0.571-5.983-1.141-11.967-1.708-17.947c-1.449-3.973-4.926-4.409-5.937-10.027l 4.449-1.085 - c 2.00-4.252, 5.665-12.802, 9.402-15.376c 1.837-0.501, 12.729-4.70, 23.642-9.022c 2.174-0.861-2.667-8.846-14.237-12.501 - c-40.042-12.647-94.991-44.956-94.991-44.956l-55.081-0.176c0.00,9.37-0.031,17.522-0.031,24.655 - C 0.002,165.037, 8.254,173.335, 18.275,177.562z" /> -<glyph unicode="" d="M 461.996,351.998L 273.498,351.998 L 238.50,351.998 L 50.002,351.998 c-9.941,0.00-18.00-8.059-18.00-18.00l0.00-251.996 c0.00-9.941, 8.059-18.00, 18.00-18.00c0.00,0.00, 60.537,0.00, 67.082,0.00 - s 10.918,4.455, 10.918,10.824c0.00,4.139,0.00,8.244,0.00,10.467c0.00,5.588-4.325,10.721-9.813,10.721c-3.684,0.00-7.893,0.00-11.67,0.00 - c-6.102,0.00-10.514,4.307-10.514,10.203c0.00,4.529,0.00,5.345,0.00,11.125s 3.349,10.66, 10.514,10.66c 3.366,0.00, 17.463,0.00, 33.267,0.00 - c 2.776,0.00, 5.604,0.00, 8.437,0.00c 15.804,0.00, 29.90,0.00, 33.267,0.00c 7.165,0.00, 10.514-4.88, 10.514-10.66s0.00-6.596,0.00-11.125 - c0.00-5.896-4.412-10.203-10.514-10.203c-3.777,0.00-7.986,0.00-11.67,0.00c-5.488,0.00-9.813-5.133-9.813-10.721c0.00-2.119,0.00-5.949,0.00-9.889 - c0.00-4.417, 3.161-11.402, 9.888-11.402c 2.066,0.00, 30.587,0.00, 69.107,0.00c 11.868,0.00, 23.317,0.00, 33.999,0.00c 38.52,0.00, 67.04,0.00, 69.106,0.00 - c 6.727,0.00, 9.888,6.985, 9.888,11.402c0.00,3.939,0.00,7.77,0.00,9.889c0.00,5.588-4.325,10.721-9.813,10.721c-3.684,0.00-7.893,0.00-11.67,0.00 - c-6.102,0.00-10.514,4.307-10.514,10.203c0.00,4.529,0.00,5.345,0.00,11.125s 3.349,10.66, 10.514,10.66c 3.366,0.00, 17.463,0.00, 33.267,0.00 - c 2.833,0.00, 5.66,0.00, 8.437,0.00c 15.804,0.00, 29.90,0.00, 33.267,0.00c 7.165,0.00, 10.514-4.88, 10.514-10.66s0.00-6.596,0.00-11.125 - c0.00-5.896-4.412-10.203-10.514-10.203c-3.777,0.00-7.986,0.00-11.67,0.00c-5.488,0.00-9.813-5.133-9.813-10.721c0.00-2.223,0.00-6.328,0.00-10.467 - c0.00-6.369, 4.373-10.824, 10.918-10.824s 67.082,0.00, 67.082,0.00c 9.941,0.00, 18.00,8.059, 18.00,18.00L 480.00,333.998 - C 479.996,343.938, 471.938,351.998, 461.996,351.998z M 222.797,160.861l-7.598,0.00 c 0.001,6.537, 0.022,12.242, 0.022,17.241 - c0.00,8.832-5.885,14.749-13.03,17.763c-7.848,3.307-28.846,11.579-31.08,12.188c-2.667,1.834-5.28,7.935-6.706,10.968 - c-1.421,0.203-2.84,0.407-4.267,0.607c 0.219,4.693, 3.126,4.947, 4.267,8.532c 1.003,3.162, 0.104,7.271, 1.698,10.20 - c 1.105,2.035, 3.607,2.048, 4.858,3.791c 1.131,1.582, 1.881,4.339, 2.232,6.277c 0.645,3.541, 1.208,8.384-0.474,11.896 - c-0.965,2.017-1.576,2.211-1.846,4.66c-0.325,2.97, 0.875,12.648, 0.926,14.742c 0.122,5.431-0.01,5.872-1.323,11.16 - c0.00,0.00-1.596,4.792-4.098,6.238l-4.986,0.86l-3.082,2.856c-12.417,7.638-25.731,2.281-32.863-0.608 - c-10.272-3.336-16.77-13.396-12.234-34.89c 0.774-3.672-2.011-5.313-1.829-7.315c 0.397-4.38, 0.482-14.913, 4.622-17.506 - c 0.383-0.24, 3.32-0.977, 3.301-0.776c 0.407-4.266, 0.813-8.535, 1.219-12.799c 1.033-2.833, 3.513-3.144, 4.233-7.149l-3.172-0.774 - c-1.427-3.033-4.041-9.13-6.706-10.968c-2.233-0.608-23.233-8.881-31.08-12.188c-7.145-3.014-12.956-8.007-12.956-17.763 - c0.00-9.759-0.145-10.958-0.022-17.239l 0.818-0.002l-7.482,0.00 L 64.159,319.50 l 158.638,0.00 L 222.797,160.861 z M 447.996,192.002L 256.002,192.002 l0.00,20.896 l 191.994,0.00 - L 447.996,192.002 z M 447.996,234.831L 256.002,234.831 l0.00,20.896 l 191.994,0.00 L 447.996,234.831 z M 447.996,288.409L 256.002,288.409 L 256.002,319.50 l 191.994,0.00 L 447.996,288.409 z" /> -<glyph unicode="" d="M 341.438,405.093c 4.086-16.444, 4.494-17.816, 4.115-34.70c-0.157-6.507-3.89-36.603-2.878-45.832 - c 0.838-7.614, 2.737-8.217, 5.736-14.491c 5.229-10.918, 3.478-25.977, 1.478-36.987c-1.095-6.023-3.424-14.597-6.944-19.514 - c-3.886-5.418-11.666-5.459-15.102-11.782c-4.955-9.108-2.16-21.884-5.28-31.717 - c-3.549-11.149-12.585-11.928-13.267-26.521c 4.435-0.626, 8.848-1.26, 13.267-1.895c 4.439-9.428, 12.56-28.395, 20.848-34.095 - c 6.946-1.894, 72.235-27.618, 96.632-37.896c 22.216-9.371, 40.514-27.77, 40.514-55.229c0.00-15.816-0.068-33.892-0.068-54.668 - l-448.883,1.07c-0.385,19.526, 0.067,23.259, 0.067,53.598c0.00,30.335, 18.068,45.858, 40.284,55.229 - c 24.396,10.277, 89.688,36.002, 96.632,37.896c 8.287,5.709, 16.414,24.667, 20.848,34.095l 9.865,2.406 - c-2.241,12.455-9.95,13.424-13.164,22.231c-1.259,13.261-2.521,26.53-3.787,39.795c 0.059-0.626-9.072,1.665-10.267,2.413 - c-12.869,8.063-13.131,40.81-14.369,54.429c-0.565,6.225, 8.094,11.327, 5.688,22.743 - C 149.30,392.502, 169.50,423.777, 201.44,434.148c 22.171,8.984, 63.565,25.642, 102.174,1.893l 9.581-8.88l 15.504-2.673 - C 336.478,419.988, 341.438,405.093, 341.438,405.093" /> -<glyph unicode="" d="M 388.92,302.163c-7.027,0.00-13.911-0.609-20.617-1.732c-16.737,54.689-68.557,94.554-129.936,94.554 - c-74.919,0.00-135.636-59.366-135.636-132.605c0.00-6.534, 0.51-12.956, 1.446-19.247c-3.597,0.413-7.228,0.692-10.935,0.692 - c-50.938,0.00-92.237-40.385-92.237-90.168c0.00-49.81, 41.299-90.174, 92.237-90.174l 130.76,0.00 l0.00,64.52 l-56.678,0.00 l 89.248,117.308 - l 89.245-117.308L 288.00,128.003 l0.00-64.519 l 100.921,0.00 c 67.425,0.00, 122.069,53.43, 122.069,119.339 - C 510.992,248.735, 456.348,302.163, 388.92,302.163z" /> -<glyph unicode="" d="M 384.00,256.00L 256.00,384.00L 128.00,256.00L 384.00,256.00 z M 128.00,160.00l 128.00-128.00l 128.00,128.00L 128.00,160.00 z" /> -<glyph unicode="" d="M 202.56,278.828l-55.689,55.691c 28.066,27.734, 66.521,44.819, 109.13,44.819 - c 42.994-0.015, 81.616-17.334, 109.84-45.497c 28.158-28.218, 45.479-66.842, 45.492-109.847l 67.541,0.00 - C 478.85,347.104, 379.10,446.855, 255.998,446.88c-61.131,0.00-116.631-24.702-156.896-64.598L 47.707,433.679l 0.003-154.851L 202.56,278.828 z - M 366.408,114.775c-28.175-28.492-67.166-46.114-110.409-46.105c-43.007,0.008-81.625,17.331-109.841,45.492 - c-28.173,28.214-45.483,66.832-45.50,109.832L 33.126,223.994 c 0.018-123.10, 99.767-222.846, 222.873-222.874 - c 61.783,0.008, 117.812,25.24, 158.173,65.894l 50.007-50.011L 464.179,168.10 L 313.086,168.10 L 366.408,114.775z" /> -<glyph unicode="" d="M 402.127,223.999l-38.709,0.00 L 199.585,223.999 l-0.003,72.491c0.00,28.30-10.741,54.276-28.521,73.284 - c-17.706,19.012-43.014,31.258-70.917,31.235c-27.905,0.022-53.211-12.224-70.917-31.235 - c-17.785-19.008-28.521-44.985-28.522-73.285l0.00-73.395 l 51.881,0.00 l0.00,11.458 L 22.26,264.875l 30.322,0.00 l0.00,31.613 - c0.00,15.106, 5.712,28.409, 14.524,37.845c 8.897,9.432, 20.351,14.772, 33.035,14.793c 12.688-0.021, 24.13-5.361, 33.027-14.793 - c 8.823-9.436, 15.436-22.738, 15.432-37.845l0.00-72.49 l-0.021,0.00 l-38.708,0.00 c-7.66,0.00-13.869-6.206-13.869-13.865l0.00-164.199 - c0.00-7.66, 6.209-13.869, 13.869-13.869l 292.255,0.00 c 7.665,0.00, 13.869,6.209, 13.869,13.869L 415.995,210.132 - C 415.996,217.793, 409.792,223.999, 402.127,223.999z" /> -<glyph unicode="" d="M 224.00,92.186L 224.00-32.00 L 32.00,160.00l 192.00,192.00l0.00-126.912 C 447.375,219.848, 437.794,376.984, 380.931,480.00 - C 521.285,328.293, 491.48,85.215, 224.00,92.186z" /> -<glyph unicode="" d="M 79.536,313.536c 26.688,0.00, 48.317,21.619, 48.317,48.307c0.00,26.688-21.633,48.308-48.317,48.308 - c-26.688,0.00-48.321-21.621-48.321-48.308C 31.215,335.156, 52.849,313.536, 79.536,313.536z M 80.632,273.397 - c-26.688,0.00-48.321-21.633-48.321-48.307c0.00-26.688, 21.634-48.32, 48.321-48.32c 26.661,0.00, 48.294,21.633, 48.294,48.32 - C 128.927,251.764, 107.293,273.397, 80.632,273.397z M 79.536,134.49c-26.688,0.00-48.321-21.633-48.321-48.32 - s 21.634-48.321, 48.321-48.321c 26.687,0.00, 48.317,21.636, 48.317,48.321C 127.856,112.857, 106.224,134.49, 79.536,134.49z - M 479.93,401.18L 179.733,401.18 l0.00-82.189 L 479.93,318.991 L 479.93,401.18 z M 179.733,44.587l 301.051,0.00 l0.00,83.06 L 179.733,127.647 L 179.733,44.587 z M 179.733,264.546l0.00-83.045 - l 301.051,0.00 l0.00,83.045 L 179.733,264.546 z" /> -<glyph unicode="" d="M 512.00,382.791c-18.839-8.354-39.082-14.001-60.33-16.54c 21.686,13.00, 38.343,33.585, 46.186,58.115 - c-20.298-12.039-42.778-20.78-66.705-25.49c-19.16,20.415-46.461,33.17-76.673,33.17c-58.011,0.00-105.044-47.029-105.044-105.039 - c0.00-8.233, 0.929-16.25, 2.72-23.939c-87.30,4.382-164.70,46.20-216.509,109.753c-9.042-15.514-14.223-33.558-14.223-52.809 - c0.00-36.444, 18.544-68.596, 46.729-87.433c-17.219,0.546-33.416,5.271-47.576,13.139c-0.011-0.438-0.011-0.878-0.011-1.321 - c0.00-50.894, 36.209-93.348, 84.262-103.00c-8.813-2.399-18.095-3.686-27.675-3.686c-6.769,0.00-13.349,0.66-19.764,1.886 - c 13.368-41.729, 52.16-72.103, 98.126-72.948c-35.95-28.174-81.243-44.967-130.458-44.967c-8.479,0.00-16.84,0.497-25.058,1.471 - c 46.485-29.806, 101.701-47.197, 161.021-47.197c 193.211,0.00, 298.868,160.063, 298.868,298.872c0.00,4.554-0.104,9.084-0.305,13.59 - C 480.109,343.227, 497.918,361.727, 512.00,382.791z" /> -<glyph unicode="" d="M 442.164,448.415l-141.789-0.003L 34.382,183.809l 183.987-183.992l 261.465,261.466L 479.834,410.746 L 442.164,448.415z - M 431.832,346.733c-14.828-14.833-38.88-14.833-53.709,0.00c-14.834,14.827-14.834,38.876,0.00,53.707 - c 14.826,14.839, 38.881,14.839, 53.709,0.004C 446.664,385.61, 446.665,361.559, 431.832,346.733" /> -<glyph unicode="" d="M 63.50,416.50l 385.00,0.00 l0.00-385.00 l-385.00,0.00 L 63.50,416.50 z" /> -<glyph unicode="" d="M 256.004,377.987l 47.684-99.429c 4.326-9.021, 12.865-15.292, 22.768-16.721l 91.258-13.162l-64.933-67.069 - c-6.173-6.376-9.206-15.158-8.284-23.984l 10.294-98.526l-82.57,52.256c-4.80,3.038-10.363,4.65-16.044,4.65l-0.304,0.00 - L 256.004,377.987 M 256.006,447.361L 181.263,291.53L 31.897,271.076l 105.769-110.336l-16.769-159.911l 134.975,85.174 - c 0.11,0.00, 0.177,0.00, 0.304,0.00l 134.885-85.363l-16.727,160.101l 105.769,109.248L 330.737,291.53L 256.006,447.361L 256.006,447.361z" /> -<glyph unicode="" d="M 256.004,377.987l 47.684-99.429c 4.326-9.021, 12.865-15.292, 22.768-16.721l 91.258-13.162l-64.933-67.069 - c-6.173-6.376-9.206-15.158-8.284-23.984l 10.294-98.526l-82.57,52.256c-4.80,3.038-10.363,4.65-16.044,4.65l-0.304,0.00 - c-5.667,0.00-11.218-1.605-16.01-4.629l-82.68-52.174l 10.32,98.411c 0.92,8.778-2.072,17.518-8.18,23.889L 94.29,249.34 - l 91.043,12.468c 9.987,1.368, 18.62,7.66, 22.979,16.749L 256.004,377.987 M 256.006,447.361L 181.263,291.53L 31.897,271.076 - l 105.769-110.336l-16.769-159.911l 134.975,85.174c 0.11,0.00, 0.177,0.00, 0.304,0.00l 134.885-85.363l-16.727,160.101l 105.769,109.248 - L 330.737,291.53L 256.006,447.361L 256.006,447.361z" /> -<glyph unicode="" d="M 391.061,0.639l-16.727,160.101l 105.769,109.248L 330.737,291.53L 256.006,447.361L 181.263,291.53L 31.897,271.076 - l 105.769-110.336l-16.769-159.911l 134.975,85.174c 0.11,0.00, 0.177,0.00, 0.304,0.00L 391.061,0.639z" /> -<glyph unicode="" d="M 32.005,64.994L 96.50,64.994L 96.50,0.496L 32.005,0.496zM 32.005,160.745L 192.024,160.745L 192.024,96.248L 32.005,96.248zM 32.005,256.496L 288.00,256.496L 288.00,191.998L 32.005,191.998zM 32.005,352.247L 383.996,352.247L 383.996,287.75L 32.005,287.75zM 32.005,447.998L 479.996,447.998L 479.996,383.501L 32.005,383.501z" /> -<glyph unicode="" d="M 32.005,447.998L 96.50,447.998L 96.50,383.50L 32.005,383.50zM 32.005,352.247L 192.024,352.247L 192.024,287.749L 32.005,287.749zM 32.005,256.496L 288.00,256.496L 288.00,191.998L 32.005,191.998zM 32.005,160.744L 383.996,160.744L 383.996,96.247L 32.005,96.247zM 32.005,64.993L 479.996,64.993L 479.996,0.496L 32.005,0.496z" /> -<glyph unicode="" d="M 160.187,61.865c-16.125,0.00-29.188-13.065-29.188-29.19c0.00-16.127, 13.063-29.188, 29.188-29.188 - c 16.113,0.00, 29.188,13.062, 29.188,29.188C 189.372,48.80, 176.30,61.865, 160.187,61.865z M 255.917,61.865 - c-16.126,0.00-29.19-13.065-29.19-29.19c0.00-16.127, 13.064-29.188, 29.19-29.188c 16.108,0.00, 29.179,13.062, 29.179,29.188 - C 285.096,48.80, 272.028,61.865, 255.917,61.865z M 255.909,13.776c-10.436,0.00-18.894,8.459-18.894,18.891 - c0.00,10.447, 8.458,18.905, 18.894,18.905c 10.435,0.00, 18.892-8.458, 18.892-18.905 - C 274.801,22.235, 266.344,13.776, 255.909,13.776z M 32.479,416.00l0.00-320.00 l 449.247,0.00 L 481.726,416.00 L 32.479,416.00 z M 441.835,136.352L 73.713,136.352 - l-0.021,238.021l 366.813,0.00 l0.00-0.012 l 1.329,0.00 L 441.835,136.352L 441.835,136.352z M 351.763,61.865 - c-16.126,0.00-29.188-13.065-29.188-29.19c0.00-16.127, 13.063-29.188, 29.188-29.188c 16.112,0.00, 29.183,13.062, 29.183,29.188 - C 380.94,48.80, 367.875,61.865, 351.763,61.865z M 351.755,13.776c-10.436,0.00-18.894,8.459-18.894,18.891 - c0.00,10.447, 8.458,18.905, 18.894,18.905c 10.438,0.00, 18.896-8.458, 18.896-18.905 - C 370.646,22.235, 362.188,13.776, 351.755,13.776z" /> -<glyph unicode="" d="M 470.70,72.193l-2.688,2.688l 0.006,0.002L 360.505,182.408c 14.938,25.732, 23.612,55.564, 23.816,87.451 - c 0.626,97.615-77.986,177.243-175.599,177.857c-0.394,0.001-0.771,0.002-1.168,0.002 - c-97.06-0.006-176.063-78.391-176.688-175.598c-0.618-97.609, 77.999-177.236, 175.597-177.859 - c 0.389-0.002, 0.766-0.004, 1.155-0.004c 32.438,0.00, 62.846,8.79, 88.998,24.075l 107.415-107.433l 0.014,0.01l 2.688-2.688 - c 8.125-8.123, 21.293-8.114, 29.41,0.00l 34.562,34.557C 478.819,50.895, 478.822,64.07, 470.70,72.193z M 300.39,177.58 - c-24.834-24.67-57.78-38.252-92.768-38.252l-0.874,0.00 c-72.589,0.467-131.271,59.908-130.813,132.503 - c 0.465,72.128, 59.516,130.811, 131.626,130.815l 0.879-0.002c 35.168-0.22, 68.146-14.123, 92.852-39.148 - c 24.706-25.025, 38.188-58.178, 37.966-93.352C 339.031,235.128, 325.229,202.25, 300.39,177.58z" /> -<glyph unicode="" d="M 33.736,60.543A60.868,61.532 540.00 1 0 155.472,60.543000000000006A60.868,61.532 540.00 1 0 33.736,60.543000000000006zM 327.928-0.988l-86.229,0.00 c0.00,116.114-93.109,210.243-207.963,210.243l0.00,0.00l0.00,87.168 - C 196.222,296.423, 327.928,163.273, 327.928-0.988zM 388.798-0.988c0.00,198.244-158.96,358.949-355.062,358.949L 33.736,447.697 c 245.118,0.00, 443.826-200.885, 443.826-448.686L 388.798-0.989 - z" /> -<glyph unicode="" d="M 32.005,447.998L 479.996,447.998L 479.996,383.50L 32.005,383.50zM 32.005,352.247L 479.996,352.247L 479.996,287.749L 32.005,287.749zM 32.005,256.496L 479.996,256.496L 479.996,191.998L 32.005,191.998zM 32.005,160.744L 479.996,160.744L 479.996,96.247L 32.005,96.247zM 32.005,64.993L 479.996,64.993L 479.996,0.496L 32.005,0.496z" /> -<glyph unicode="" d="M 224.01,351.904l-67.942,0.00 L 256.012,472.979L 355.937,351.90l-67.932,0.00 l-0.001-255.803l 67.932,0.00 L 255.99-24.979 - l-99.927,121.076l 67.943,0.00 L 224.01,351.904z" /> -<glyph unicode="" d="M 383.904,255.996l0.00,67.942 l 121.074-99.944L 383.90,124.069l0.00,67.932 l-255.803,0.001l0.00-67.932 L 7.022,224.016 - l 121.076,99.926l0.00-67.943 L 383.904,255.996z" /> -<glyph unicode="" d="M 288.00,355.814L 288.00,480.00 l 192.00-192.00L 288.00,96.00L 288.00,222.912 C 64.625,228.153, 74.206,71.016, 131.069-32.00 - C-9.286,119.707, 20.52,362.785, 288.00,355.814z" /> -<glyph unicode="" d="M 346.842,54.611c 21.076,11.557, 39.271,26.125, 54.399,43.698c 15.199,17.575, 26.912,37.946, 35.285,61.009 - c 7.671,21.094, 11.471,40.729, 11.471,64.424c0.00,2.285-0.105,192.828-0.105,192.828L 256.00,416.57 l0.00-192.018 l 93.728,0.00 - c-0.599-26.107-5.876-45.195-15.728-63.121c-10.163-18.525-29.167-32.827-58.054-42.75l-3.201-1.092l0.00-85.777 l 5.313,0.703 - C 302.758,35.683, 325.696,43.07, 346.842,54.611M 51.917,118.301l-3.171-1.092l0.00-85.779 l 5.316,0.704c 24.666,3.168, 47.64,10.556, 68.791,22.097 - c 21.074,11.557, 39.229,26.125, 54.392,43.698c 15.206,17.575, 26.949,37.947, 35.288,61.01 - c 7.67,21.093, 11.469,40.728, 11.469,64.424c0.00,2.284-0.076,192.825-0.076,192.825L 32.005,416.188 l0.00-192.017 l 93.729,0.00 - c-0.563-26.107-5.872-45.194-15.724-63.122C 99.839,142.525, 80.804,128.223, 51.917,118.301" /> -<glyph unicode="" d="M 133.16,393.389c-21.076-11.557-39.271-26.125-54.399-43.698c-15.199-17.575-26.912-37.947-35.285-61.009 - c-7.671-21.094-11.471-40.728-11.471-64.423c0.00-2.285, 0.105-192.828, 0.105-192.828l 191.892,0.00 L 224.002,223.447 l-93.728,0.00 - c 0.599,26.107, 5.876,45.195, 15.728,63.122c 10.163,18.524, 29.167,32.827, 58.054,42.75l 3.201,1.091L 207.257,416.188 l-5.313-0.704 - C 177.244,412.317, 154.306,404.929, 133.16,393.389M 428.085,329.699l 3.171,1.091L 431.256,416.57 l-5.316-0.704c-24.666-3.168-47.64-10.555-68.791-22.097 - c-21.074-11.557-39.229-26.125-54.392-43.698c-15.206-17.576-26.949-37.947-35.288-61.01 - C 259.799,267.968, 256.00,248.334, 256.00,224.638c0.00-2.284, 0.076-192.825, 0.076-192.825l 191.921,0.00 L 447.997,223.829 l-93.729,0.00 - c 0.563,26.107, 5.872,45.195, 15.724,63.122C 380.163,305.475, 399.198,319.777, 428.085,329.699" /> -<glyph unicode="" d="M 461.998,287.998l-44.865,0.00 l0.00,74.991 l-85.277,85.21L 96.004,448.199 l0.00-160.201 l-46.00,0.00 c-9.941,0.00-18.00-8.059-18.00-18.00l0.00-187.996 - c0.00-9.941, 8.059-18.00, 18.00-18.00l 46.00,0.00 l0.00-64.50 l 321.128,0.00 l0.00,64.50 l 44.865,0.00 c 9.941,0.00, 18.00,8.059, 18.00,18.00L 479.997,269.998 - C 479.998,279.938, 471.939,287.998, 461.998,287.998z M 96.004,97.50L 64.255,97.50 l0.00,93.654 l0.00,0.848 l 31.749,0.00 L 96.004,97.50 z M 319.37,415.375 - l 64.453-63.377L 319.37,351.998 L 319.37,415.375 z M 383.998,32.002L 128.004,32.002 l0.00,160.00 l 255.994,0.00 L 383.998,32.002 z M 383.998,287.998L 128.004,287.998 l0.00,128.00 l 159.998,0.00 l0.00-96.00 - l 95.996,0.00 L 383.998,287.998 z M 448.298,97.50l-31.165,0.00 l0.00,94.502 l 30.118,0.00 l 1.047,0.00 L 448.298,97.50 zM 160.127,96.002L 351.50,96.002L 351.50,62.629L 160.127,62.629zM 160.127,161.437L 351.50,161.437L 351.50,128.064L 160.127,128.064z" /> -<glyph unicode="" d="M 427.182,320.352L 325.629,320.352 c 6.396,3.992, 12.695,8.69, 18.575,14.393c 30.401,29.163, 39.269,69.303, 19.804,89.555 - c-7.468,7.76-17.991,11.484-29.858,11.484c-19.118,0.00-41.686-9.681-60.437-27.676c-7.679-7.383-13.959-15.469-18.775-23.762 - c-4.834,8.293-11.11,16.378-18.793,23.762c-18.751,18.001-41.301,27.676-60.419,27.676c-11.881,0.00-22.435-3.724-29.903-11.484 - c-19.458-20.252-10.587-60.392, 19.814-89.555c 5.896-5.703, 12.166-10.401, 18.606-14.393L 84.818,320.352 L 64.002,320.352 l0.00-98.164 l 32.00,0.00 l0.00-222.048 l 319.994,0.00 - L 415.996,222.188 l 32.00,0.00 l0.00,98.164 L 427.182,320.352 z M 272.212,353.958c 2.513,11.443, 10.075,23.888, 20.734,34.136 - c 15.289,14.705, 31.298,19.919, 41.21,19.919c 2.606,0.00, 7.359-0.37, 9.83-2.943c 2.662-2.773, 3.327-8.961, 1.711-16.206 - c-2.525-11.47-10.088-23.908-20.733-34.146c-15.303-14.691-31.298-19.905-41.196-19.905c-2.607,0.00-7.359,0.383-9.845,2.943 - C 271.248,340.529, 270.61,346.714, 272.212,353.958z M 275.77,316.343l0.00-92.344 l-41.668,0.00 l0.00,92.344 L 275.77,316.343 z M 164.137,388.864 - c-1.599,7.244-0.954,13.432, 1.71,16.206c 2.481,2.573, 7.22,2.943, 9.872,2.943c 9.885,0.00, 25.894-5.214, 41.183-19.933 - c 10.659-10.241, 18.208-22.686, 20.73-34.122c 1.599-7.244, 0.954-13.429-1.724-16.202c-2.469-2.56-7.238-2.943-9.845-2.943 - c-9.892,0.00-25.867,5.214-41.183,19.905C 174.235,364.957, 166.672,377.394, 164.137,388.864z M 411.896,128.002L 275.77,128.002 l0.00-124.127 l-41.668,0.00 - L 234.102,128.002 L 100.935,128.002 l0.00,32.165 l 133.167,0.00 l0.00,46.00 l 41.668,0.00 l0.00-46.00 l 136.126,0.00 L 411.896,128.002 z" /> -<glyph unicode="" d="M 255.982,360.004L 418.982,128.01L 93.018,128.002 z" /> -<glyph unicode="" d="M 392.004,223.983L 160.01,386.982L 160.002,61.018 z" /> -<glyph unicode="" d="M 119.995,223.983L 351.988,386.982L 351.996,61.018 z" /> -<glyph unicode="" d="M 255.982,87.996L 418.982,319.99L 93.018,319.998 z" /> -<glyph unicode="" d="M 415.996,255.998L 287.998,255.998L 287.998,383.998L 224.002,383.998L 224.002,255.998L 96.002,255.998L 96.002,192.002L 224.002,192.002L 224.002,64.002L 287.998,64.002L 287.998,192.002L 415.996,192.002 z" /> -<glyph unicode="" d="M 96.002,451.331L 436.998,224.00L 96.002-3.331L 96.002,451.331 z" /> -<glyph unicode="" d="M 461.173,351.998L 351.786,351.998 l-25.911,53.007c0.00,0.00-5.165,10.993-18.42,10.993c-10.21,0.00-74.079,0.00-102.888,0.00 - c-14.414,0.00-19.231-10.909-19.231-10.909l-25.131-53.091L 49.372,351.998 c-9.941,0.00-18.00-8.06-18.00-18.00l0.00-251.736 c0.00-9.941, 8.059-18.00, 18.00-18.00l 411.801,0.00 - c 9.941,0.00, 18.00,8.059, 18.00,18.00L 479.173,333.998 C 479.173,343.938, 471.114,351.998, 461.173,351.998z M 255.271,105.43 - c-60.684,0.00-110.007,49.37-110.007,110.016c0.00,60.665, 49.339,110.012, 110.007,110.012c 60.656,0.00, 110.022-49.347, 110.022-110.012 - C 365.294,154.791, 315.928,105.43, 255.271,105.43zM 255.271,281.456c-36.397,0.00-66.007-29.597-66.007-66.01c0.00-36.39, 29.609-66.001, 66.007-66.001 - c 36.404,0.00, 66.008,29.611, 66.008,66.001C 321.279,251.859, 291.676,281.456, 255.271,281.456z" /> -<glyph unicode="" d="M 351.528,188.046c-6.412,3.971-16.018,2.871-21.464-2.468l-42.484-42.472 - c-5.434-5.339-14.086-5.339-19.425,0.00l-95.473,95.506c-5.345,5.346-5.345,14.079,0.00,19.424l 40.016,40.003 - c 5.353,5.346, 6.131,14.763, 1.798,20.933L 141.695,422.18c-4.299,6.164-12.724,7.372-18.626,2.676c0.00,0.00-56.792-45.067-56.792-86.471 - c0.00-169.442, 137.367-306.795, 306.795-306.795c 41.425,0.00, 81.708,76.009, 81.708,76.009c 3.542,6.666, 1.194,15.413-5.217,19.383 - L 351.528,188.046z" /> -<glyph unicode="" d="M 440.316,414.613c 12.849-6.288, 24.047-15.243, 32.251-26.241c 17.269-23.15, 22.118-54.686, 14.418-93.733 - c-7.78-39.513-25.208-72.868-50.583-97.022c-4.641-4.852-9.611-9.373-14.902-13.54c-27.178-21.401-61.498-32.714-99.254-32.714 - l-6.056,0.00 L 202.217,151.363 L 169.935,0.00l-66.212,0.00 l 5.043,23.15l 23.064,0.00 l 32.281,151.363l 94.136,0.00 c 90.124,0.00, 165.469,55.538, 185.629,149.967 - C 466.736,431.398, 390.076,480.00, 324.171,480.00L 99.532,480.00 L0.00,23.15l 76.016,0.00 L 64.00-32.00l 131.83,0.00 l 32.281,151.363l 94.135,0.00 - c 90.125,0.00, 165.47,55.539, 185.63,149.968C 524.733,348.171, 487.474,395.297, 440.316,414.613z M 211.172,386.959l 64.565,0.00 - c 32.296,0.00, 53.801-27.769, 44.394-62.478c-8.068-34.72-41.693-62.488-75.32-62.488l-61.879,0.00 L 211.172,386.959z" /> -<glyph unicode="" d="M 96.002,415.333l 96.00,0.00 l0.00-382.667 l-96.00,0.00 L 96.002,415.333 z M 321.413,415.333l 94.583,0.00 l0.00-382.667 l-94.583,0.00 L 321.413,415.333 z" /> -<glyph unicode="" d="M 68.436,311.144l 22.881,0.00 L 91.317,424.772 L 72.669,424.772 c0.00-0.991-0.271-2.505-0.857-4.541c-0.991-3.39-2.465-6.122-4.367-8.158 - c-2.813-2.975-6.479-4.957-10.958-5.948c-2.813-0.63-7.739-1.099-14.763-1.42l0.00-15.192 l 26.712,0.00 L 68.436,311.144 z M 64.685,219.003 - c-11.843-8.466-19.345-16.45-22.532-24.032c-3.296-6.726-5.033-14.174-5.252-22.318l 77.729,0.00 l0.00,19.666 L 65.09,192.319 - c 1.393,2.357, 3.135,4.396, 5.197,6.162c 2.063,1.795, 5.895,4.662, 11.49,8.627l 8.926,6.324 - c 7.525,5.33, 12.938,10.153, 16.233,14.494c 5.01,6.523, 7.528,13.985, 7.528,22.385c0.00,10.959-3.563,19.76-10.663,26.404 - c-7.101,6.658-16.666,9.98-28.669,9.98c-15.191,0.00-25.774-5.653-31.723-16.986c-3.139-5.948-4.876-13.745-5.251-23.391 - l 21.675,0.00 c 0.269,6.363, 1.099,10.999, 2.492,13.933c 2.465,5.051, 7.069,7.582, 13.879,7.582c 4.956,0.00, 8.761-1.594, 11.413-4.769 - c 2.648-3.188, 3.988-7.167, 3.988-11.977c0.00-5.895-2.331-11.32-6.966-16.276C 81.618,231.623, 74.974,226.358, 64.685,219.003z - M 110.151,86.539c-4.18,3.832-7.364,5.732-9.592,5.732c 2.947,1.146, 5.813,3.297, 8.547,6.432 - c 4.341,5.037, 6.515,11.199, 6.515,18.514c0.00,10.344-3.617,18.567-10.905,24.73c-7.261,6.135-16.825,9.217-28.722,9.217 - c-6.381,0.00-11.789-0.777-16.156-2.331c-4.396-1.526-8.198-3.778-11.391-6.672c-4.283-4.126-7.422-8.601-9.431-13.45 - c-1.876-5.546-2.947-11.413-3.162-17.576l 22.801,0.00 c-0.104,6.109, 1.183,10.985, 3.889,14.656s 6.938,5.492, 12.70,5.492 - c 5.01,0.00, 8.896-1.50, 11.651-4.447c 2.759-3.001, 4.152-6.859, 4.152-11.574c0.00-7.342-2.706-12.164-8.118-14.576 - c-3.135-1.439-8.654-2.189-16.558-2.304l0.00-17.495 c 8.063,0.00, 13.981-0.771, 17.764-2.305c 6.591-2.76, 9.913-8.199, 9.913-16.371 - c0.00-6.162-1.795-10.904-5.358-14.20c-3.563-3.269-7.717-4.896-12.513-4.896c-7.823,0.00-13.209,2.974-16.156,8.976 - c-1.604,3.271-2.411,7.396-2.411,12.354L 33.632,64.445 c 0.402-9.893, 2.385-17.87, 6.002-23.979 - c 6.832-11.494, 19.05-17.228, 36.625-17.228c 14.254,0.00, 25.025,3.985, 32.312,11.943c 7.288,7.957, 10.936,17.20, 10.936,27.73 - C 119.503,72.90, 116.368,80.777, 110.151,86.539z M 480.145,401.296L 179.949,401.296 l0.00-82.189 l 300.188,0.00 L 480.145,401.296L 480.145,401.296z - M 179.949,44.703L 481.00,44.703 l0.00,83.059 L 179.949,127.762 L 179.949,44.703 z M 179.949,264.663l0.00-83.045 L 481.00,181.618 l0.00,83.045 L 179.949,264.663 z" /> -<glyph unicode="" d="M 409.947,370.39c-12.927,12.917-33.873,12.917-46.794,0.00c-12.92-12.922-12.92-33.87,0.00-46.794l0.00,0.006 - c 29.647-29.682, 44.347-68.266, 44.382-107.154c-0.035-38.892-14.729-77.478-44.382-107.157 - c-29.673-29.648-68.26-44.339-107.149-44.376c-38.896,0.037-77.481,14.731-107.146,44.376 - c-29.653,29.68-44.353,68.266-44.389,107.157c 0.036,38.894, 14.731,77.472, 44.384,107.148 - c 12.919,12.919, 12.926,33.869, 0.005,46.789c-12.92,12.923-33.869,12.923-46.79,0.006 - c-42.455-42.423-63.812-98.336-63.771-153.942c-0.037-55.606, 21.315-111.52, 63.771-153.944 - c 42.419-42.446, 98.332-63.802, 153.938-63.766l 0.142,0.00 c 55.563-0.002, 111.409,21.35, 153.80,63.766 - c 42.444,42.425, 63.813,98.338, 63.767,153.944C 473.751,272.053, 452.394,327.963, 409.947,370.39zM 256.704,191.357c 18.271,0.00, 33.085,14.812, 33.085,33.083L 289.789,413.278 c0.00,18.271-14.813,33.085-33.085,33.085 - c-18.274,0.00-33.086-14.816-33.086-33.085l0.00-188.836 C 223.618,206.173, 238.429,191.357, 256.704,191.357z" /> -<glyph unicode="" d="M 90.68,160.51L 126.742,124.447L 253.718,251.426L 380.691,124.448L 416.754,160.51L 253.718,323.551 z" /> -<glyph unicode="" d="M 196.729,60.963L 160.666,97.025L 287.643,224.001L 160.667,350.975L 196.729,387.037L 359.768,224.001 z" /> -<glyph unicode="" d="M 317.207,60.963L 353.27,97.025L 226.291,224.001L 353.269,350.975L 317.207,387.037L 154.166,224.001 z" /> -<glyph unicode="" d="M 416.754,287.49L 380.691,323.553L 253.716,196.574L 126.742,323.552L 90.68,287.49L 253.716,124.449 z" /> -<glyph unicode="" d="M 504.979,223.994L 383.904,323.938L 383.904,255.996L 288.005,255.997L 288.005,351.90L 355.937,351.90L 256.012,472.979L 156.067,351.904L 224.01,351.904L 224.009,255.998L 128.098,255.999L 128.098,323.942L 7.021,224.016L 128.098,124.07L 128.098,192.002L 224.008,192.002L 224.007,96.098L 156.063,96.098L 255.99-24.979L 355.936,96.098L 288.004,96.098L 288.004,192.001L 383.90,192.001L 383.90,124.069 z" /> -<glyph unicode="" d="M 96.002,255.998L 415.996,255.998L 415.996,192.002L 96.002,192.002z" /> -<glyph unicode="" d="M 256.00,447.998c-83.058,0.00-150.374-67.286-150.374-150.374c0.00-73.704, 64.874-169.622, 116.446-249.789 - c 39.066-60.729, 29.329-61.07, 67.853-0.004c 50.575,80.171, 116.449,176.088, 116.449,249.773 - C 406.374,380.652, 339.058,447.998, 256.00,447.998z M 256.00,225.785c-39.67,0.00-71.858,32.16-71.858,71.858 - c0.00,39.699, 32.188,71.839, 71.858,71.839c 39.669,0.00, 71.857-32.16, 71.857-71.858C 327.857,257.925, 295.669,225.785, 256.00,225.785z" /> -<glyph unicode="" d="M 256.398,162.378c-4.897,0.00-9.814,1.545-13.934,4.642L 32.156,324.88l0.00-234.203 c0.00-16.487, 13.413-27.675, 29.90-27.675 - l 388.676,0.00 c 16.492,0.00, 29.263,11.188, 29.263,27.675L 479.995,324.88 L 269.999,167.02C 265.882,163.923, 261.288,162.378, 256.398,162.378zM 451.282,352.018L 256.398,205.719L 61.513,352.018 z" /> -<glyph unicode="" d="M 255.875,451.175L 63.605,334.688l0.00-221.367 l 49.933-29.402L 113.538,305.29 l 142.381,86.565l 142.49-86.43 - l 0.599-0.343l-0.059-220.832l 49.445,29.07L 448.394,334.688 L 255.875,451.175z M 281.322,314.901l0.00-258.805 l-25.447-15.566l-25.477,15.624 - L 230.398,314.697 l-65.943-40.617l0.00-221.313 l 91.42-55.942l 92.20,56.333L 348.075,274.234 L 281.322,314.901z" /> -<glyph unicode="" d="M 402.127,223.937l-38.709,0.00 l-0.006,64.061c0.00,30.667-11.64,58.792-30.863,79.345 - c-19.156,20.557-46.447,33.753-76.542,33.729c-30.104,0.024-57.396-13.172-76.551-33.729 - c-19.233-20.553-30.871-48.679-30.876-79.345l0.00-64.061 l-38.708,0.00 c-7.66,0.00-13.869-6.205-13.869-13.864l0.00-164.201 - c0.00-7.659, 6.209-13.869, 13.869-13.869l 292.255,0.00 c 7.665,0.00, 13.869,6.21, 13.869,13.869L 415.996,210.07 - C 415.996,217.731, 409.792,223.937, 402.127,223.937z M 312.404,223.937L 199.588,223.937 l0.00,64.061 c0.00,17.699, 6.701,33.356, 17.115,44.50 - c 10.497,11.135, 24.163,17.544, 39.304,17.566c 15.13-0.022, 28.798-6.427, 39.287-17.566c 10.416-11.143, 17.11-26.801, 17.11-44.50 - L 312.404,223.937 z" /> -<glyph unicode="" d="M 221.533,116.203l-37.033-34.33c-8.995-8.319-20.297-12.079-31.93-11.681c-11.109,0.454-21.96,5.06-30.329,14.057 - l-3.382,3.668c-8.303,8.996-12.084,20.234-11.68,31.698c 0.463,11.303, 5.053,22.158, 14.054,30.524l 85.934,79.645 - c 5.046,4.659, 10.772,7.889, 16.835,9.763c0.00,8.613, 0.088,61.287, 0.088,72.72c-23.642-2.68-46.787-12.709-65.50-30.063 - l-85.936-79.642c-23.266-21.53-35.834-50.785-36.921-80.225c-1.155-29.401, 9.047-59.642, 30.701-83.012l 3.384-3.651 - c 21.434-23.149, 50.545-35.81, 80.027-36.919l 0.164-0.006c 29.321-1.117, 59.624,8.968, 83.062,30.703l 37.031,34.311 - c 14.476,13.415, 15.337,36.023, 1.922,50.495C 258.617,128.737, 236.008,129.60, 221.533,116.203zM 476.256,325.848c 1.204,29.423-9.102,59.554-30.659,82.823l-3.384,3.669c-21.592,23.319-50.937,35.824-80.354,36.912 - c-29.42,1.152-59.596-9.082-82.895-30.69l-35.342-32.747c-14.475-13.428-15.338-36.038-1.926-50.513s 36.02-15.337, 50.497-1.925 - l 35.336,32.748c 9.029,8.334, 20.232,12.101, 31.604,11.716c 11.40-0.484, 22.282-5.09, 30.62-14.086l 3.416-3.654 - c 8.303-9.013, 12.081-20.216, 11.683-31.538c-0.469-11.435-5.095-22.336-14.095-30.703l-85.932-79.628 - c-5.012-4.634-10.729-7.859-16.826-9.736c0.00-14.327,0.00-56.327,0.00-72.708c 23.514,2.70, 46.64,12.627, 65.392,30.027l 85.967,79.63 - C 462.698,267.083, 475.199,296.426, 476.256,325.848zM 119.299,339.487c 2.929-2.929, 6.768-4.394, 10.606-4.394s 7.678,1.464, 10.606,4.394c 5.858,5.858, 5.858,15.355,0.00,21.213 - L 44.314,456.897c-5.857,5.858-15.355,5.858-21.213,0.00c-5.858-5.858-5.858-15.355,0.00-21.213L 119.299,339.487zM 192.002,352.095c 8.284,0.00, 15.00,6.716, 15.00,15.00L 207.002,446.436 c0.00,8.284-6.716,15.00-15.00,15.00s-15.00-6.716-15.00-15.00l0.00-79.341 - C 177.002,358.811, 183.718,352.095, 192.002,352.095zM 126.343,287.913c0.00,8.284-6.716,15.00-15.00,15.00L 32.002,302.913 c-8.284,0.00-15.00-6.716-15.00-15.00s 6.716-15.00, 15.00-15.00l 79.341,0.00 - C 119.627,272.913, 126.343,279.629, 126.343,287.913zM 392.621,108.95c-5.857,5.857-15.355,5.857-21.213,0.00c-5.858-5.857-5.858-15.355,0.00-21.213l 96.198-96.198 - c 2.929-2.929, 6.768-4.394, 10.606-4.394s 7.678,1.465, 10.606,4.394c 5.858,5.857, 5.858,15.355,0.00,21.213L 392.621,108.95zM 319.919,96.342c-8.284,0.00-15.00-6.716-15.00-15.00l0.00-79.341 c0.00-8.284, 6.716-15.00, 15.00-15.00s 15.00,6.716, 15.00,15.00l0.00,79.341 - C 334.919,89.626, 328.203,96.342, 319.919,96.342zM 385.577,160.523c0.00-8.284, 6.716-15.00, 15.00-15.00l 79.342,0.00 c 8.284,0.00, 15.00,6.716, 15.00,15.00s-6.716,15.00-15.00,15.00l-79.342,0.00 - C 392.293,175.523, 385.577,168.808, 385.577,160.523z" /> -<glyph unicode="" d="M 221.533,116.203l-37.033-34.33c-8.995-8.319-20.297-12.079-31.93-11.681c-11.109,0.454-21.96,5.06-30.329,14.057 - l-3.382,3.668c-8.303,8.996-12.084,20.234-11.68,31.698c 0.463,11.303, 5.053,22.158, 14.054,30.524l 85.934,79.645 - c 9.028,8.335, 20.233,12.099, 31.639,11.698c 11.368-0.465, 22.252-5.074, 30.62-14.072l 3.381-3.669l 52.421,48.589l-3.386,3.652 - l-6.175,6.648c-2.637,2.84-5.609,5.156-8.84,6.959c-19.25,14.601-42.242,22.475-65.31,23.321 - c-29.449,1.155-59.625-9.097-82.928-30.707l-85.936-79.642c-23.266-21.53-35.834-50.785-36.921-80.225 - c-1.155-29.401, 9.047-59.642, 30.701-83.012l 3.384-3.651c 21.434-23.149, 50.545-35.81, 80.027-36.919l 0.164-0.006 - c 29.321-1.117, 59.624,8.968, 83.062,30.703l 37.031,34.311c 14.476,13.415, 15.337,36.023, 1.922,50.495 - C 258.617,128.737, 236.008,129.60, 221.533,116.203zM 445.597,408.67l-3.384,3.669c-21.592,23.319-50.937,35.824-80.354,36.912c-29.42,1.152-59.596-9.082-82.895-30.69 - l-35.342-32.747c-14.475-13.428-15.338-36.038-1.926-50.513s 36.02-15.337, 50.497-1.925l 35.336,32.748 - c 9.029,8.334, 20.232,12.101, 31.604,11.716c 11.40-0.484, 22.282-5.09, 30.62-14.086l 3.416-3.654 - c 8.303-9.013, 12.081-20.216, 11.683-31.538c-0.469-11.435-5.095-22.336-14.095-30.703l-85.932-79.628 - c-8.996-8.318-20.266-12.10-31.931-11.687c-11.108,0.447-21.927,5.045-30.295,14.061l-3.386,3.652l-52.42-48.587l 3.38-3.654 - c 21.403-23.132, 50.511-35.808, 79.998-36.896l 0.194-0.008c 29.318-1.118, 59.588,8.954, 83.024,30.702l 85.967,79.63 - c 23.34,21.639, 35.841,50.982, 36.897,80.404C 477.46,355.271, 467.154,385.401, 445.597,408.67z" /> -<glyph unicode="" d="M 351.996,415.998L 351.996,237.18L 96.002,448.00L 96.002,0.00L 351.996,210.82L 351.996,32.002L 447.996,32.002L 447.996,415.998 z" /> -<glyph unicode="" d="M 482.178,233.834L 342.742,379.832c-2.575,2.665-6.122,4.166-9.828,4.166L 45.484,383.998 c-7.561,0.00-13.687-6.126-13.687-13.688 - l0.00-291.995 c0.00-7.562, 6.126-13.688, 13.687-13.688l 287.43,0.00 c 3.706,0.00, 7.253,1.502, 9.828,4.166l 139.436,145.998 - C 487.324,220.098, 487.324,228.527, 482.178,233.834z M 327.112,95.931L 64.002,95.931 L 64.002,352.124 l 263.11,0.00 l 126.18-127.811L 327.112,95.931zM 267.427,325.312L 193.763,250.351L 120.094,325.312L 94.06,299.724L 168.178,224.312L 94.06,148.894L 120.094,123.306L 193.763,198.27L 267.427,123.306L 293.464,148.894L 219.349,224.312L 293.464,299.724 z" /> -<glyph unicode="" d="M 29.815,214.791l 139.436-145.998c 2.575-2.664, 6.122-4.166, 9.828-4.166l 287.429,0.00 c 7.562,0.00, 13.688,6.127, 13.688,13.688 - L 480.196,370.31 c0.00,7.561-6.126,13.688-13.688,13.688L 179.079,383.998 c-3.706,0.00-7.253-1.501-9.828-4.166L 29.815,233.834 - C 24.669,228.527, 24.669,220.098, 29.815,214.791z M 58.701,224.312l 126.18,127.811l 263.108,0.00 l0.00-256.193 L 184.881,95.93 L 58.701,224.312zM 218.529,299.724L 292.644,224.312L 218.529,148.894L 244.566,123.306L 318.229,198.27L 391.898,123.306L 417.932,148.894L 343.814,224.312L 417.932,299.724L 391.898,325.312L 318.229,250.351L 244.566,325.312 z" /> -<glyph unicode="" d="M 48.073,0.002l 79.011,0.017l 0.01,45.529l 49.23,0.013l 0.007,50.45l 47.674-0.009L 224.00,141.556 - l 50.566,0.009l 37.571,32.034c 44.065-12.063, 92.902-1.09, 127.277,33.169c 51.184,51.347, 50.762,134.801-0.911,186.701 - c-51.781,51.553-135.238,51.98-186.399,0.611c-34.485-34.339-45.464-83.306-33.298-127.414L 32.002,79.861l 0.291-64.071 - C 32.355,4.206, 36.603,0.243, 48.073,0.002z M 361.38,316.957c-13.714,13.921-13.843,36.085-0.298,49.49 - c 13.639,13.763, 35.798,13.644, 49.488-0.301c 13.755-13.50, 13.886-35.67, 0.313-49.499 - C 397.273,303.30, 375.108,303.429, 361.38,316.957z" /> -<glyph unicode="" d="M 295.446,31.498L 108.404,31.498 l 3.648,21.205c 21.455,8.767, 42.379,14.598, 62.836,17.525l 91.339,305.806 - c-9.792,1.964-45.405,14.313-54.792,18.273l 5.114,21.19l 187.044,0.00 l-4.396-21.19c-22.019-8.825-58.625-17.432-62.836-18.273 - l-91.311-305.806c 10.509-2.121, 47.089-13.814, 54.069-17.525L 295.446,31.498z" /> -<glyph unicode="" d="M 335.49,115.189c-9.558,0.00-47.096-57.998-67.553-57.998c-5.459,0.00-8.17,4.787-8.17,9.558 - c0.00,10.909, 7.506,27.979, 11.58,38.216l 49.13,133.011c 24.56,66.191-6.834,83.922-36.151,83.922 - c-39.572,0.00-75.062-19.786-102.332-45.708c-5.076-5.068-16.971-16.651-26.377-27.822c-7.691-9.13-6.813-18.64-2.32-21.406 - c 5.626-3.464, 14.265,3.051, 18.405,7.886c 14.991,17.518, 34.313,42.019, 50.521,42.019c 5.462,0.00, 11.605-6.136, 6.832-18.407 - l-47.737-120.078c-4.796-11.606-27.983-67.556-27.983-100.294c0.00-25.929, 17.049-37.517, 41.61-37.517 - c 68.91,0.00, 148.724,84.603, 148.724,104.389C 343.668,111.104, 338.891,115.189, 335.49,115.189zM 321.828,447.423c-30.018,0.00-55.938-24.553-55.938-54.568c0.00-27.979, 18.435-46.41, 46.398-46.41 - c 30.703,0.00, 56.615,23.196, 56.615,54.591C 368.904,429.016, 349.137,447.423, 321.828,447.423z" /> -<glyph unicode="" d="M 352.381,251.944c 19.508,0.00, 35.292,16.00, 35.292,35.758c0.00,19.743-15.784,35.765-35.292,35.765 - c-19.45,0.00-35.277-16.022-35.277-35.765C 317.104,267.944, 332.931,251.944, 352.381,251.944zM 244.799,175.919l-88.125,94.968L 96.748,158.586l0.00-30.938 l 297.645,0.00 C 356.489,160.775, 276.541,231.63, 276.541,231.63 - L 244.799,175.919zM 32.00,384.00l0.00-319.782 l 447.50,0.00 L 479.50,384.00 L 32.00,384.00 z M 73.072,104.542l-0.019,237.854l 365.385,0.00 l0.00-0.012 l 1.32,0.00 l 0.005-237.842L 73.072,104.542 z" /> -<glyph unicode="" d="M 395.841,276.128L 395.841,360.032L 339.902,360.032L 339.902,332.064L 256.00,415.968L 32.255,191.932L 96.50,191.932L 96.50,31.598L 224.551,31.598L 224.551,159.598L 288.50,159.598L 288.50,31.598L 416.50,31.598L 416.50,191.932L 479.742,191.932 - z" /> -<glyph unicode="" d="M 415.459,383.458C 372.866,426.051, 316.235,449.508, 256.00,449.508c-60.235,0.00-116.865-23.457-159.458-66.05 - C 53.949,340.865, 30.492,284.235, 30.492,224.00s 23.457-116.866, 66.05-159.459c 42.593-42.593, 99.223-66.05, 159.458-66.05 - c 60.235,0.00, 116.866,23.457, 159.459,66.05s 66.05,99.224, 66.05,159.459S 458.052,340.865, 415.459,383.458z M 256.00,31.092 - C 149.631,31.092, 63.093,117.63, 63.093,224.00c0.00,106.369, 86.538,192.907, 192.907,192.907 - c 106.37,0.00, 192.908-86.538, 192.908-192.907C 448.908,117.63, 362.37,31.092, 256.00,31.092zM 342.291,356.486c-21.754,19.24-51.033,28.861-87.842,28.861c-34.986,0.00-63.238-9.507-84.759-28.519 - c-21.525-19.015-27.814-41.741-29.486-68.966l 55.262,0.271c 4.107,19.011, 9.93,25.194, 20.881,34.474 - c 10.951,9.275, 24.563,13.917, 40.843,13.917c 16.882,0.00, 30.305-4.449, 40.269-13.346c 9.959-8.898, 14.943-19.586, 14.943-32.056 - c0.00-8.976-2.816-17.19-8.441-24.641c-3.651-4.716-14.83-14.68-33.538-29.887c-18.711-15.212-31.186-28.917-37.421-41.083 - c-6.238-12.17-9.277-27.145-9.125-35.508l 64.113,0.00 c-0.307,17.643, 10.188,26.305, 23.728,37.561 - c 26.158,21.766, 43.235,38.952, 51.22,51.578c 7.986,12.624, 11.979,26.01, 11.979,40.155 - C 374.916,314.849, 364.039,337.244, 342.291,356.486zM 223.877,128.011L 287.99,128.011L 287.99,63.903L 223.877,63.903z" /> -<glyph unicode="" d="M 32.002,447.998L 160.002,447.998L 160.002,319.998L 32.002,319.998zM 192.00,447.998L 320.00,447.998L 320.00,319.998L 192.00,319.998zM 351.996,447.998L 479.996,447.998L 479.996,319.998L 351.996,319.998zM 32.002,288.00L 160.002,288.00L 160.002,160.00L 32.002,160.00zM 192.00,288.00L 320.00,288.00L 320.00,160.00L 192.00,160.00zM 351.996,288.00L 479.996,288.00L 479.996,160.00L 351.996,160.00zM 32.002,128.002L 160.002,128.002L 160.002,0.002L 32.002,0.002zM 192.00,128.002L 320.00,128.002L 320.00,0.002L 192.00,0.002zM 351.996,128.002L 479.996,128.002L 479.996,0.002L 351.996,0.002z" /> -<glyph unicode="" d="M 279.533,448.00c0.00,0.00-100.479,0.00-133.971,0.00c-60.06,0.00-116.585-45.503-116.585-98.211c0.00-53.863, 40.941-97.333, 102.044-97.333 - c 4.249,0.00, 8.378,0.085, 12.421,0.376c-3.965-7.593-6.801-16.144-6.801-25.021c0.00-14.969, 8.052-27.105, 18.234-37.012 - c-7.693,0.00-15.121-0.224-23.227-0.224C 57.259,190.576,0.00,143.195,0.00,94.064c0.00-48.389, 62.771-78.656, 137.167-78.656 - c 84.812,0.00, 131.652,48.122, 131.652,96.514c0.00,38.801-11.447,62.036-46.843,87.067c-12.107,8.571-35.265,29.418-35.265,41.672 - c0.00,14.36, 4.098,21.434, 25.714,38.323c 22.156,17.312, 37.836,41.651, 37.836,69.958c0.00,33.703-15.01,66.549-43.186,77.386l 42.477,0.00 - L 279.533,448.00z M 232.74,120.271c 1.063-4.486, 1.642-9.104, 1.642-13.814c0.00-39.10-25.196-69.655-97.487-69.655 - c-51.421,0.00-88.558,32.552-88.558,71.65c0.00,38.321, 46.063,70.222, 97.481,69.666c 12.00-0.127, 23.185-2.058, 33.335-5.345 - C 207.066,153.359, 227.092,142.393, 232.74,120.271z M 150.409,266.112c-34.52,1.032-67.318,38.613-73.276,83.93 - c-5.958,45.333, 17.185,80.021, 51.694,78.995c 34.505-1.037, 67.318-37.407, 73.278-82.729 - C 208.059,300.978, 184.911,265.079, 150.409,266.112z M 416.00,352.00L 416.00,448.00 l-32.00,0.00 l0.00-96.00 l-96.00,0.00 l0.00-32.00 l 96.00,0.00 l0.00-96.00 l 32.00,0.00 l0.00,96.00 l 96.00,0.00 l0.00,32.00 L 416.00,352.00 z" /> -<glyph unicode="" d="M 248.023,234.684L 247.35,235.809L 246.563,238.057L 247.124,238.73L 246.786,240.303L 244.764,238.73L 245.214,237.381L 245.775,235.248L 244.764,235.248L 244.764,234.237L 245.889,233.562 zM 241.955,236.259L 242.293,234.684L 243.979,235.471L 244.426,236.82L 243.753,237.493 zM 244.09,245.134L 244.426,246.033L 243.529,246.932L 241.73,247.043L 241.843,245.697 zM 256.338,254.011L 256.898,253.788L 257.012,254.684L 256.338,255.022L 256.785,256.145L 254.764,255.022L 255.55,253.338 zM 261.279,257.27L 260.158,257.831L 259.37,257.043L 260.831,256.82 zM 256.00,449.078C 131.695,449.078, 30.922,348.308, 30.922,224.00S 131.695-1.078, 256.00-1.078 - c 124.303,0.00, 225.078,100.771, 225.078,225.078S 380.303,449.078, 256.00,449.078z M 62.028,224.00c0.00,41.132, 12.838,79.241, 34.674,110.627 - l 2.504-1.877l-1.513-6.073l 5.559-1.521l-1.013,8.093l 4.553,0.503l0.00,10.625 l 4.552,0.00 c0.00,0.00, 0.80-2.062, 1.642-4.224 - c 0.923-2.376, 1.899-4.88, 1.899-4.88l 5.055-5.568c0.00,0.00-6.068-1.508-8.088-1.508c-2.022,0.00-1.013-8.093-1.013-8.093l 7.077-2.525 - l 4.572,8.444l 10.601,11.782l 5.056,15.674l 9.612,9.111l-5.565,4.033l 6.073,4.047l 0.505,5.568l-17.701-5.056l-0.558,0.666 - c 9.638,8.19, 20.077,15.455, 31.201,21.653l 8.299-3.614l-5.559-10.623l-11.133,0.00 l-2.024-9.604l 9.106,0.00 l 13.149,8.095l 9.106,9.096 - l 1.513,8.599l-13.149,1.009l 9.103,6.073l 8.598-1.521l-1.514-9.099l 11.632,7.091l 2.027-5.568l 2.53-8.095l-6.577-8.093 - l-7.082-6.572l-10.623,1.521l 5.06-10.619l-9.61,1.517l-16.184-16.692l 4.046-5.567l 13.149,1.018l 11.128,3.546l 14.167,1.508 - l 6.572,1.519c0.00,0.00,0.00,4.046-0.507,6.572c-0.501,2.53, 5.06-0.50, 5.06-0.50l 6.071,3.532l 4.552,14.167l 16.688,7.595l-2.525,4.037 - l 4.046,5.064l-13.148,2.026l 3.539,5.056l-16.692,5.568l-8.599,0.00 l 3.034,7.581l 3.539,3.547l-0.284,0.284 - c 14.076,3.244, 28.72,5.018, 43.787,5.018c 23.479,0.00, 45.979-4.172, 66.808-11.817l-0.507-1.191l-8.423,0.563l0.00-5.064 l 3.376-2.246 - l0.00-4.493 l 2.806-3.93l-10.111,6.176l-6.735-3.372l 3.368-7.873l 1.688-8.986l 4.492-5.064l 10.665-1.684l-2.242-4.493l-2.25-6.752 - l 9.556-6.176l-0.563-2.81l-17.979,15.176l-1.116-5.627l 7.859-7.865l 4.493-1.684l-10.11-2.246l-1.126-5.064l-7.298,7.315 - l-4.501,9.548l-1.688,9.557l-4.501-5.618l 3.376-13.487l 5.618-3.943l-2.242-12.914l-3.376,1.688l 0.563-6.752l-5.063,0.563 - l-5.052,7.315l-6.176,0.00 l-8.995,1.125l-8.999-0.563l-8.423-6.752l-5.622-9.548l-11.804-8.994l-1.125-5.056l0.00-6.189 l 2.809-6.177 - l 5.623,4.493l 1.683-3.367l 2.814-5.056l 0.563-1.134l 2.809-3.372l 5.061,3.368l-0.563,12.366l 6.176,7.873 - c0.00,0.00, 0.313,1.332, 0.664,2.869c 0.479,2.046, 1.024,4.433, 1.024,4.433l 2.242,6.19l 3.943-0.563l-1.122-5.064l-2.259-11.232 - l 10.691,1.125l 3.935-1.125l-8.436-2.255l 1.12-5.618l-9.557-6.176l 0.563-6.19l-8.423-2.25l-1.684-4.493l-6.748,2.247l-4.497,0.00 - l0.00,9.557 l-5.06-1.697l0.00-5.055 l-14.051-11.245l-7.869-2.809l-3.369-3.93l-11.245,2.809l-0.563-5.056l 7.306-2.817l-0.563-10.104 - l-20.235,0.563l-2.81-4.493l-2.809-7.874l-3.376-6.752l 5.06-5.618l 5.623-6.739L 207.109,224.00l 1.125,6.739l 3.939,3.38l 6.743,2.247 - l-0.563,4.493l 6.185,1.688l 8.988,1.684l 5.623-6.739l 10.115-7.315l 4.496-7.297l0.00-3.371 l 5.614,3.371l-2.805,5.051l 1.122,5.626 - l-5.057,2.247l-4.496,6.176l 2.809,8.999l 5.051-7.311l 7.302-5.618l 2.805-10.12l 7.311-5.614l 1.696-6.189l 3.372,7.311l-1.125,3.372 - l 1.685,2.809l 10.664,8.994l 2.251,11.246l 4.501,3.372l 5.618-0.563l 8.432,8.436l 0.563-6.752l 12.353-3.93l0.00-6.19 l-10.103,0.00 - l-15.175-7.86l-12.366-6.752l 3.371-7.302l 11.236-2.246l 6.19-2.81l 6.743,4.492l 0.554-19.113l-19.113-3.93l-20.209,5.627 - l-7.873-6.189l 3.367-3.368l-6.189,1.121l-19.664,7.311l-5.618-0.571l-4.496,7.311l0.00,8.995 l-10.121,0.00 l-5.617,1.125l-17.987-3.943 - l-14.05,1.134l-6.181-3.381l-3.934-0.563l-2.251-7.297l-12.924-8.999l-17.989-13.486l-1.125-17.413l-5.06-11.245l 0.563-6.735 - l 4.497-7.878l 12.929-21.91l 13.487-6.185l 22.481-1.688l-1.125,9.562l-5.06,2.806l 2.247,5.055l 3.938-4.492l 3.93-11.805 - l 16.861-1.125l 6.743-6.734l 9.553-3.943l 1.125-16.297l 10.121-12.928l 9.553-16.855l-8.428-10.119l 8.607-13.391 - C 145.055,33.967, 62.028,119.269, 62.028,224.00z M 322.468,41.723l 23.449,17.047l-8.423,20.802l 26.975,35.397l 8.423,22.482 - l 3.93,12.37l-14.032-6.753l-8.44-1.688l-20.784,12.933l-6.19,14.05l-7.868,7.869l-10.111,22.473l 8.423-6.739l 15.747-17.422 - l 5.618-7.868l 11.228-5.619l 3.376-14.612l 13.495,8.986l 16.292,20.238l 7.869,20.79l-6.186,5.051l-3.372,6.189l-3.938-7.311 - l-7.864-8.985l-11.24,12.366l-3.368,9.544l 7.869-1.685l 7.864-3.93l 11.241,3.93l 6.753-2.245l 17.967,12.365l 10.133-5.626 - l 6.176,3.38l 13.438-21.158l 6.656,6.348l 0.132,8.063l 0.554,24.169l 4.132,11.452c 1.008-7.99, 1.583-16.116, 1.583-24.38 - C 449.972,140.229, 396.859,68.854, 322.468,41.723z" /> -<glyph unicode="" d="M 116.838,355.64c-25.396,0.00-47.242-8.403-65.542-25.208c-19.043-17.926-28.57-40.33-28.57-67.218 - c0.00-17.926, 5.188-34.731, 15.647-50.416c 9.337-14.563, 19.09-23.903, 31.889-28.012l0.00-1.121 - c-12.799-5.224-18.482-18.295-18.482-39.209c0.00-16.062, 5.686-28.011, 18.482-35.854l0.00-1.121 - c-35.327-11.572-51.496-33.047-51.496-64.414c0.00-27.268, 11.874-47.244, 35.033-59.939C 72.094-26.959, 95.588-32.00, 123.972-32.00 - c 69.085,0.00, 103.703,28.941, 103.703,86.832c0.00,36.223-26.661,58.441-80.063,66.658c-12.323,1.863-21.644,6.348-27.991,13.445 - c-4.854,4.854-7.271,9.709-7.271,14.563c0.00,13.816, 7.479,21.848, 22.41,24.088c 22.779,3.357, 41.364,13.912, 55.743,31.648 - c 14.375,17.74, 21.565,38.559, 21.565,62.458c0.00,7.469-2.26,15.498-5.244,24.086c 9.709,2.244, 16.524,4.297, 21.646,6.166L 228.47,355.64 - c-22.526-8.964-43.495-13.442-61.421-13.442C 151.361,351.159, 135.136,355.64, 116.838,355.64z M 123.00,76.115 - c 31.372,0.00, 47.052-9.521, 47.052-28.57c0.00-20.168-14.377-30.246-43.132-30.246c-32.862,0.00-49.293,9.711-49.293,29.127 - C 77.626,66.221, 92.749,76.115, 123.00,76.115z M 119.079,224.00c-23.527,0.00-35.293,12.882-35.293,38.654 - c0.00,27.631, 11.766,41.453, 35.293,41.453c 11.201,0.00, 19.979-4.298, 26.326-12.884c 5.229-7.845, 7.845-17.18, 7.845-28.011 - C 153.25,237.073, 141.857,224.00, 119.079,224.00z M 289.395,480.00c-10.828,0.00-20.069-4.107-27.727-12.324 - c-7.661-8.218-11.489-18.108-11.489-29.688c0.00-11.205, 3.829-20.91, 11.489-29.129c 7.654-8.217, 16.896-12.32, 27.727-12.32 - c 10.455,0.00, 19.514,4.104, 27.17,12.32c 7.656,8.219, 11.48,17.924, 11.48,29.129c0.00,11.58-3.824,21.472-11.48,29.688 - C 308.905,475.893, 299.85,480.00, 289.395,480.00z M 320.768,352.001l-63.303,0.00 c 0.748-7.168-0.32-18.021-0.32-35.57l0.00-174.216 - c0.00-17.928, 1.068-32.387, 0.32-38.018l 63.303,0.00 c-0.75,8.188-2.697,22.334-2.697,41.379L 318.071,317.549 - C 318.067,333.981, 320.018,344.833, 320.768,352.001z M 460.371,157.90c-16.437,0.00-24.541,12.514-24.541,37.533L 435.83,298.753 l 24.932,0.00 - c 4.479,0.00, 8.516,0.246, 13.559-0.123c 5.043-0.374, 7.076-0.125, 9.64-0.125L 483.961,352.00 l-48.129,0.00 l0.00,23.808 c0.00,8.961, 1.407,17.151, 2.526,22.271 - l-64.979,0.00 c 1.121-5.12, 1.014-12.938, 1.014-23.395L 374.393,352.00 l-28.16,0.00 l0.00-53.494 c 7.683,1.12, 14.545,1.678, 19.398,1.678l 8.762-0.559l0.00-0.292 l0.00,0.00 - l0.00-101.101 c0.00-31.371, 3.979-54.336, 11.818-68.90c 10.461-19.42, 28.811-29.129, 56.067-29.129c 19.425,0.00, 36.56,3.732, 49.357,11.205 - l0.00,56.016 C 481.398,161.074, 471.944,157.90, 460.371,157.90z" /> -<glyph unicode="" d="M 444.797,255.998L 398.073,302.721L 479.835,384.482L 416.485,447.833L 334.724,366.071L 288.00,412.795L 288.00,255.998 - zM 67.123,255.998L 113.847,302.721L 32.085,384.482L 95.435,447.833L 177.196,366.071L 223.92,412.795L 223.92,255.998 - zM 444.797,191.92L 398.073,145.196L 479.835,63.436L 416.485,0.085L 334.724,81.846L 288.00,35.123L 288.00,191.92 - zM 67.123,191.92L 113.847,145.196L 32.085,63.436L 95.435,0.085L 177.196,81.846L 223.92,35.123L 223.92,191.92 - z" /> -<glyph unicode="" d="M 177.285,208.636L 78.726,110.077L 32.004,156.801L 32.004,0.004L 188.801,0.004L 142.079,46.728L 240.636,145.286 zM 188.801,447.996L 32.004,447.996L 32.004,291.199L 78.726,337.922L 177.285,239.364L 240.636,302.714L 142.079,401.272 zM 334.714,208.636L 271.364,145.286L 369.923,46.728L 323.199,0.004L 479.996,0.004L 479.996,156.801L 433.272,110.077 zM 323.199,447.996L 369.923,401.272L 271.364,302.714L 334.714,239.364L 433.272,337.922L 479.996,291.199L 479.996,447.996 z" /> -<glyph unicode="" d="M 466.766,288.599c-68.667,0.00-338.019,0.00-356.766,0.00c-21.50,0.00-26.203-21.411-26.203-21.411L 55.08,82.854 - c-1.239-7.888-14.837-6.083-13.466,2.646l 15.637,202.498c0.00,0.00, 4.249,32.602, 39.249,32.602c 28.227,0.00, 262.052,0.00, 351.496,0.00L 447.996,335.31 - c0.00,9.222-7.475,16.688-16.691,16.688L 216.757,351.998 l-43.624,58.994l-0.089-0.026c-3.031,3.094-7.244,5.032-11.916,5.032L 48.686,415.998 - c-9.211,0.00-16.683-7.475-16.683-22.561l 1.505-312.185c0.00-9.223, 7.472-16.688, 16.683-16.688l 381.114,0.00 - c 9.217,0.00, 16.688,7.465, 16.691,16.688l 35.601,185.334C 483.597,266.586, 489.336,288.285, 466.766,288.599z" /> -<glyph unicode="" d="M 431.305,351.998L 216.757,351.998 l-43.624,58.994l-0.089-0.026c-3.031,3.094-7.244,5.032-11.916,5.032L 48.686,415.998 - c-9.211,0.00-16.683-7.475-16.683-22.561l 1.505-312.185c0.00-9.223, 7.472-16.688, 16.683-16.688l 381.114,0.00 - c 9.217,0.00, 16.688,7.465, 16.691,16.688L 447.996,287.50 l0.00,47.81 C 447.996,344.532, 440.521,351.998, 431.305,351.998z M 240.00,95.205 - c-62.186,0.00-112.596,50.41-112.596,112.596c0.00,62.181, 50.41,112.591, 112.596,112.591c 62.184,0.00, 112.596-50.41, 112.596-112.591 - C 352.596,145.615, 302.184,95.205, 240.00,95.205zM 223.48,241.22L 161.002,241.223L 161.002,174.746L 223.478,174.745L 223.478,130.076L 317.874,207.981L 223.48,285.901 z" /> -<glyph unicode="" d="M 160.50,223.696L 319.50,223.696L 319.50,191.902L 160.50,191.902zM 431.305,351.998L 216.757,351.998 l-43.624,58.994l-0.089-0.026c-3.031,3.094-7.244,5.032-11.916,5.032L 48.686,415.998 - c-9.211,0.00-16.683-7.475-16.683-22.561l 1.505-312.185c0.00-9.223, 7.472-16.688, 16.683-16.688l 381.114,0.00 - c 9.217,0.00, 16.688,7.465, 16.691,16.688L 447.996,287.50 l0.00,47.81 C 447.996,344.532, 440.521,351.998, 431.305,351.998z M 240.00,95.205 - c-62.186,0.00-112.596,50.41-112.596,112.596c0.00,62.181, 50.41,112.591, 112.596,112.591c 62.184,0.00, 112.596-50.41, 112.596-112.591 - C 352.596,145.615, 302.184,95.205, 240.00,95.205z" /> -<glyph unicode="" d="M 431.305,351.998L 216.757,351.998 l-43.624,58.994l-0.089-0.026c-3.031,3.094-7.244,5.032-11.916,5.032L 48.686,415.998 - c-9.211,0.00-16.683-7.475-16.683-22.561l 1.505-312.185c0.00-9.223, 7.472-16.688, 16.683-16.688l 381.114,0.00 - c 9.217,0.00, 16.688,7.465, 16.691,16.688L 447.996,287.50 l0.00,47.81 C 447.996,344.532, 440.521,351.998, 431.305,351.998z M 240.00,95.205 - c-62.186,0.00-112.596,50.41-112.596,112.596c0.00,62.181, 50.41,112.591, 112.596,112.591c 62.184,0.00, 112.596-50.41, 112.596-112.591 - C 352.596,145.615, 302.184,95.205, 240.00,95.205zM 255.898,287.297L 224.102,287.297L 224.102,223.696L 160.50,223.696L 160.50,191.902L 224.102,191.902L 224.102,128.301L 255.898,128.301L 255.898,191.902L 319.50,191.902L 319.50,223.696L 255.898,223.696 z" /> -<glyph unicode="" d="M 431.305,351.998L 216.757,351.998 l-43.624,58.994l-0.089-0.026c-3.031,3.094-7.244,5.032-11.916,5.032L 48.686,415.998 - c-9.211,0.00-16.683-7.475-16.683-22.561l 1.505-312.185c0.00-9.223, 7.472-16.688, 16.683-16.688l 381.114,0.00 - c 9.217,0.00, 16.688,7.465, 16.691,16.688L 447.996,287.50 l0.00,47.81 C 447.996,344.532, 440.521,351.998, 431.305,351.998z" /> -<glyph unicode="" d="M 63.252,447.998L 95.65,447.998L 95.65,0.002L 63.252,0.002zM 401.471,415.998l-95.14-95.145l 96.834-96.851L 160.01,224.002 L 160.01,415.998 L 401.471,415.998 M 478.723,447.998L 128.01,447.998 l0.00-255.996 l 352.40,0.00 - L 351.583,320.851L 478.723,447.998L 478.723,447.998z" /> -<glyph unicode="" d="M 351.583,320.851L 478.723,447.998L 128.01,447.998L 128.01,192.002L 480.41,192.002 zM 63.252,447.998L 95.65,447.998L 95.65,0.002L 63.252,0.002z" /> -<glyph unicode="" d="M 160.003,415.998L 160.003,237.18L 415.996,448.00L 415.996,0.00L 160.003,210.82L 160.003,32.002L 64.003,32.002L 64.003,415.998 z" /> -<glyph unicode="" d="M 63.145,447.998L 63.145,383.998L 213.144,212.286L 213.144,40.859L 298.856-1.997L 298.856,212.286L 448.855,383.998L 448.855,447.998 z" /> -<glyph unicode="" d="M 503.611,146.991l-45.414,44.548c 13.105,11.496, 24.191,22.291, 32.663,31.172 - c-2.193,2.337-23.248,22.273-27.113,26.138c-2.402-2.128-104.908-114.769-207.756-114.769 - c-86.444,0.00-181.754,86.349-207.225,115.06c-7.362-6.769-24.63-23.638-27.437-26.429 - c 8.803-9.076, 19.852-19.751, 32.662-30.985L 8.387,146.991c-8.287-8.13-8.416-21.441-0.285-29.729 - c 4.118-4.196, 9.559-6.301, 15.007-6.301c 5.313,0.00, 10.63,2.001, 14.723,6.017l 48.974,48.041 - c 15.042-11.323, 31.434-22.418, 48.718-32.302l-29.787-62.356c-5.004-10.48-0.569-23.027, 9.908-28.036 - c 2.051-0.979, 4.182-1.594, 6.316-1.876c 8.783-1.159, 17.691,3.36, 21.715,11.785l 29.501,61.759 - c 20.12-8.455, 40.923-14.608, 61.80-17.17l0.00-64.193 c0.00-11.61, 9.412-21.022, 21.023-21.022s 21.023,9.412, 21.023,21.022l0.00,64.198 - c 20.775,2.549, 41.49,8.65, 61.519,17.008l 30.169-61.632c 4.108-8.391, 13.056-12.824, 21.826-11.583 - c 2.136,0.304, 4.261,0.941, 6.299,1.943c 10.428,5.108, 14.742,17.697, 9.639,28.126l-30.236,61.768 - c 17.484,9.933, 34.023,21.076, 49.119,32.401l 48.812-47.88c 4.092-4.018, 9.407-6.018, 14.72-6.018 - c 5.447,0.00, 10.89,2.104, 15.009,6.301C 512.029,125.55, 511.90,138.861, 503.611,146.991z" /> -<glyph unicode="" d="M 255.992,349.715c-116.967,0.00-234.758-127.177-234.758-127.177s 117.791-127.166, 234.758-127.166 - c 116.984,0.00, 234.773,127.166, 234.773,127.166S 372.977,349.715, 255.992,349.715z M 255.992,133.905 - c-49.705,0.00-90.00,40.261-90.00,90.011c0.00,49.703, 40.296,89.989, 90.00,89.989c 49.729,0.00, 90.023-40.286, 90.023-89.989 - C 346.018,174.166, 305.721,133.905, 255.992,133.905zM 255.992,268.006c-24.32,0.00-44.104-19.78-44.104-44.09c0.00-24.313, 19.784-44.112, 44.104-44.112 - c 24.332,0.00, 44.126,19.80, 44.126,44.112C 300.12,248.225, 280.326,268.006, 255.992,268.006z" /> -<glyph unicode="" d="M 468.328,387.262l-47.784,48.149c-12.065,12.141-31.647,12.192-43.80,0.158l-30.197-29.965l 91.373-92.049 - l 30.208,29.928C 480.271,355.555, 480.381,375.141, 468.328,387.262z M 85.751,146.693l 91.38-92.024l 238.881,237.066 - l-91.432,92.096L 85.751,146.693z M 49.536,65.123L 32.512,2.57l 62.703,16.563l 58.26,15.346l-88.153,88.86L 49.536,65.123z" /> -<glyph unicode="" d="M 322.097,448.198L 64.002,448.198 l0.00-448.696 l 352.527,0.00 L 416.529,354.50 L 322.097,448.198z M 319.368,415.375l 64.453-63.377l-64.453,0.00 L 319.368,415.375 z - M 383.996,32.002L 96.002,32.002 L 96.002,415.998 L 288.00,415.998 l0.00-96.00 l 95.996,0.00 L 383.996,32.002 zM 127.404,207.801c0.00-62.186, 50.41-112.596, 112.596-112.596c 62.184,0.00, 112.596,50.41, 112.596,112.596 - c0.00,62.181-50.412,112.591-112.596,112.591C 177.814,320.392, 127.404,269.982, 127.404,207.801z M 319.50,223.696l0.00-31.794 l-159.00,0.00 l0.00,31.794 - L 319.50,223.696 z" /> -<glyph unicode="" d="M 322.097,448.198L 64.002,448.198 l0.00-448.696 l 352.527,0.00 L 416.529,354.50 L 322.097,448.198z M 319.368,415.375l 64.453-63.377l-64.453,0.00 L 319.368,415.375 z - M 383.996,32.002L 96.002,32.002 L 96.002,415.998 L 288.00,415.998 l0.00-96.00 l 95.996,0.00 L 383.996,32.002 zM 127.404,207.801c0.00-62.186, 50.41-112.596, 112.596-112.596c 62.184,0.00, 112.596,50.41, 112.596,112.596 - c0.00,62.181-50.412,112.591-112.596,112.591C 177.814,320.392, 127.404,269.982, 127.404,207.801z M 319.50,223.696l0.00-31.794 l-63.602,0.00 - l0.00-63.602 l-31.797,0.00 l0.00,63.602 L 160.50,191.902 l0.00,31.794 l 63.602,0.00 l0.00,63.601 l 31.797,0.00 l0.00-63.601 L 319.50,223.696 z" /> -<glyph unicode="" d="M 322.097,448.198L 64.002,448.198 l0.00-448.696 l 352.527,0.00 L 416.529,354.50 L 322.097,448.198z M 319.368,415.375l 64.453-63.377l-64.453,0.00 L 319.368,415.375 z - M 96.002,32.002L 96.002,415.998 L 288.00,415.998 l0.00-96.00 l 95.996,0.00 l0.00-287.996 L 96.002,32.002 z" /> -<glyph unicode="" d="M 339.229,149.373c 0.009-0.672, 0.054-1.321, 0.054-1.988c0.00-68.036-55.351-123.383-123.39-123.383 - c-68.031,0.00-123.383,55.347-123.383,123.383c0.00,41.116, 20.236,77.581, 51.258,100.014l-4.197,36.865 - c-47.956-26.845-80.46-78.124-80.46-136.878c0.00-86.454, 70.329-156.783, 156.783-156.783c 73.287,0.00, 134.963,50.55, 152.064,118.604 - L 339.229,149.373zM 155.871,409.356A39.893,39.893 540.00 1 0 235.657,409.356A39.893,39.893 540.00 1 0 155.871,409.356zM 452.941,100.229l-89.518,125.166c-4.685,6.555-12.505,9.654-20.441,8.976c-0.591,0.056-1.184,0.105-1.783,0.105 - L 238.941,234.476 l-2.539,22.263l 76.006,0.00 c 8.842,0.00, 16.009,7.165, 16.009,16.004c0.00,8.837-7.167,16.001-16.009,16.001l-79.647,0.00 l-4.157,36.556 - c-2.432,21.383-21.74,36.741-43.119,34.307c-21.383-2.437-36.741-21.741-34.305-43.117l 11.749-103.237 - c 2.276-19.967, 19.247-34.658, 38.883-34.55c 0.067,0.00, 0.129-0.015, 0.201-0.015l 133.794,0.00 l 76.77-107.339 - c 7.328-10.256, 22.315-12.11, 33.468-4.13C 457.188,75.191, 460.277,89.973, 452.941,100.229z" /> -<glyph unicode="" d="M 380.476,96.165A36.94,36.94 540.00 1 0 454.356,96.16500000000002A36.94,36.94 540.00 1 0 380.476,96.16500000000002zM 137.084,133.105c-20.396,0.00-36.936-16.539-36.936-36.939c0.00-20.402, 16.54-36.941, 36.936-36.941 - c 20.406,0.00, 36.945,16.539, 36.945,36.941C 174.03,116.566, 157.491,133.105, 137.084,133.105zM 32.089,351.998L 319.996,351.998L 319.996,160.002L 32.089,160.002zM 447.996,287.998l-96.123,0.00 L 351.873,133.11 L 165.726,133.11 c 11.016-8.554, 18.113-21.914, 18.113-36.944l 186.825,0.00 - c0.00,25.823, 20.926,46.754, 46.752,46.754c 25.818,0.00, 46.752-20.931, 46.752-46.754l 6.414,0.00 c 5.15,0.00, 9.328,4.176, 9.328,9.332l0.00,18.005 - L 479.91,223.999 L 447.996,287.998z M 384.295,209.539l 0.115,46.223l 41.301,0.00 l 22.285-46.223L 384.295,209.539 zM 108.444,133.11L 32.196,133.11 L 32.10,119.348c0.00,0.00-1.209-23.182, 22.168-23.182s 25.151,0.00, 25.151,0.00L 90.33,96.166 - C 90.33,111.196, 97.428,124.557, 108.444,133.11z" /> -<glyph unicode="" d="M 462.879,367.121L 399.121,430.885L 256.00,287.769L 111.883,431.883L 48.119,368.119L 192.234,224.002L 47.115,78.885L 110.879,15.114L 256.00,160.239L 400.125,16.112L 463.883,79.883L 319.762,224.002 z" /> -<glyph unicode="" d="M 256.50,450.167c-123.433,0.00-223.495-30.976-223.495-58.084c0.00-7.91,0.00-78.09,0.00-86.00c0.00-27.108, 100.063-58.084, 223.495-58.084 - c 123.434,0.00, 223.496,30.976, 223.496,58.084c0.00,7.91,0.00,78.09,0.00,86.00C 479.996,419.19, 379.934,450.167, 256.50,450.167z M 256.50,352.218 - c-92.096,0.00-166.755,16.965-166.755,34.191c0.00,17.226, 74.659,37.191, 166.755,37.191c 92.097,0.00, 166.757-19.965, 166.757-37.191 - C 423.257,369.183, 348.597,352.218, 256.50,352.218zM 256.50,74.967c-121.174,0.00-219.815,27.18-223.385,53.602c-0.066-0.492-0.11-0.986-0.11-1.482c0.00-7.91,0.00-70.09,0.00-78.00 - c0.00-27.108, 100.063-58.084, 223.495-58.084c 123.434,0.00, 223.496,30.976, 223.496,58.084c0.00,7.91,0.00,70.09,0.00,78.00 - c0.00,0.496-0.044,0.99-0.11,1.482C 476.315,102.146, 377.675,74.967, 256.50,74.967zM 256.50,199.684c-121.174,0.00-219.815,30.18-223.385,56.602c-0.066-0.492-0.11-0.986-0.11-1.482c0.00-7.91,0.00-70.09,0.00-78.00 - c0.00-27.108, 100.063-58.084, 223.495-58.084c 123.434,0.00, 223.496,30.976, 223.496,58.084c0.00,7.91,0.00,70.09,0.00,78.00 - c0.00,0.496-0.044,0.99-0.11,1.482C 476.315,229.863, 377.675,199.684, 256.50,199.684z" /> -<glyph unicode="" d="M 32.003,384.085l0.00-256.083 l 447.994,0.00 L 479.997,384.085 L 32.003,384.085 z M 447.997,192.002 - c-16.979,0.00-31.844-16.662-31.844-32.00c-85.539,0.00-312.823,0.00-319.494,0.00c0.00,15.988-12.478,33.004-32.656,33.004 - c0.00,34.088,0.00,115.911,0.00,126.904c 23.808,0.00, 30.772,17.437, 30.772,32.176c 13.851,0.00, 306.301,0.00, 321.537,0.00 - c0.00-15.313, 14.154-31.521, 31.685-31.521C 447.997,310.141, 447.997,199.875, 447.997,192.002zM 195.765,256.043A60.235,76.165 540.00 1 0 316.235,256.043A60.235,76.165 540.00 1 0 195.765,256.043zM 32.003,96.002L 479.997,96.002L 479.997,64.002L 32.003,64.002z" /> -<glyph unicode="" d="M 479.748,355.514c0.00,15.757-12.77,28.528-28.528,28.528L 60.78,384.042 c-15.756,0.00-28.528-12.771-28.528-28.528l0.00-263.027 - c0.00-15.759, 12.772-28.528, 28.528-28.528l 390.44,0.00 c 15.759,0.00, 28.528,12.77, 28.528,28.528L 479.748,355.514 z M 75.163,352.042l 362.455,0.00 - c 5.122,0.00, 10.629-5.509, 10.629-10.628l0.00-53.173 L 64.252,288.241 l0.00,53.173 C 64.252,346.533, 70.047,352.042, 75.163,352.042z M 437.617,96.046 - L 75.163,96.046 c-5.116,0.00-10.91,3.203-10.91,8.32L 64.253,223.217 l 383.994,0.00 l0.00-118.851 C 448.246,99.249, 442.739,96.046, 437.617,96.046z" /> -<glyph unicode="" d="M 259.116,414.717C 136.071,417.138, 34.79,341.32, 32.90,245.367c-0.652-33.359, 10.793-64.75, 31.171-91.627l-0.004,0.00 - c 35.045-45.026-32.065-135.984-32.065-135.984l 141.793,62.193c 24.33-7.688, 50.769-12.167, 78.473-12.713 - c 123.042-2.428, 224.325,73.396, 226.217,169.349C 480.369,332.54, 382.155,412.291, 259.116,414.717z" /> -<glyph unicode="" d="M 256.00-0.496C 132.211-0.496, 31.504,100.216, 31.504,224.00C 31.504,347.789, 132.211,448.496, 256.00,448.496 - c 123.789,0.00, 224.496-100.708, 224.496-224.496C 480.496,100.216, 379.789-0.496, 256.00-0.496z M 256.00,394.617 - c-94.078,0.00-170.617-76.539-170.617-170.617c0.00-94.082, 76.54-170.617, 170.617-170.617c 94.087,0.00, 170.617,76.535, 170.617,170.617 - C 426.617,318.078, 350.087,394.617, 256.00,394.617zM 357.43,238.941l-83.642,0.00 l0.00,102.79 c0.00,12.339-9.996,22.339-22.345,22.339c-12.339,0.00-22.344-10.00-22.344-22.339l0.00-125.454 - c0.00-12.165, 9.87-22.025, 22.029-22.025L 357.43,194.252 c 12.339,0.00, 22.345,10.005, 22.345,22.344 - C 379.774,228.936, 369.769,238.941, 357.43,238.941z" /> -<glyph unicode="" d="M 182.964,32.002c-25.798,69.719-85.798,136.165-148.651,176.979l 29.583,48.595 - c 36.183-14.439, 115.92-60.484, 144.845-103.773c 47.26,107.101, 130.196,204.28, 238.443,265.649l 30.501-48.477 - c-106.48-79.458-184.927-215.304-222.155-338.973L 182.964,32.002 z" /> -<glyph unicode="" d="M 463.271,351.953L 127.855,351.953 L 53.729,425.512C 43.326,435.835, 26.523,435.77, 16.20,425.367 - C 5.877,414.964, 5.942,398.162, 16.345,387.839l 86.328-85.666l 34.09-156.646c0.00-9.678, 7.846-17.525, 17.525-17.525l 268.546,0.00 - c 9.686,0.00, 17.525,7.848, 17.525,17.525l 40.437,188.903C 480.797,344.112, 472.957,351.953, 463.271,351.953zM 334.075,48.083A47.978,47.978 540.00 1 0 430.031,48.08300000000003A47.978,47.978 540.00 1 0 334.075,48.08300000000003zM 144.259,48.083A47.978,47.978 540.00 1 0 240.215,48.08300000000003A47.978,47.978 540.00 1 0 144.259,48.08300000000003z" /> -<glyph unicode="" d="M 256.00,447.998C 132.289,447.998, 32.001,347.711, 32.001,224.00S 132.289,0.002, 256.00,0.002S 479.999,100.289, 479.999,224.00 - S 379.711,447.998, 256.00,447.998z M 145.692,334.307c 29.464,29.464, 68.639,45.691, 110.308,45.691 - c 28.047,0.00, 54.958-7.361, 78.544-21.152L 121.152,145.459c-13.79,23.585-21.151,50.495-21.151,78.541 - C 100.001,265.668, 116.228,304.843, 145.692,334.307z M 366.308,113.693c-29.464-29.465-68.639-45.691-110.308-45.691 - c-28.047,0.00-54.958,7.361-78.544,21.153l 213.387,213.394c 13.794-23.587, 21.156-50.50, 21.156-78.549 - C 411.999,182.331, 395.772,143.157, 366.308,113.693z" /> -<glyph unicode="" d="M 172.063,193.823L 217.844,193.823L 217.844,148.066L 172.063,148.066zM 236.52,132.598L 282.242,132.598L 282.242,86.848L 236.52,86.848zM 172.063,132.598L 217.844,132.598L 217.844,86.848L 172.063,86.848zM 172.063,255.05L 217.844,255.05L 217.844,209.319L 172.063,209.319zM 368.475,344.174c 10.469,0.00, 18.949,8.495, 18.949,18.977L 387.424,428.535 c-0.001,10.481-8.481,18.964-18.949,18.964 - c-10.494,0.00-18.979-8.483-18.979-18.964l0.00-65.385 C 349.50,352.669, 357.981,344.174, 368.475,344.174zM 144.372,344.174c 10.467,0.00, 18.946,8.495, 18.946,18.977L 163.318,428.535 c0.00,10.481-8.479,18.964-18.946,18.964 - c-10.495,0.00-18.979-8.483-18.979-18.964l0.00-65.385 C 125.395,352.669, 133.877,344.174, 144.372,344.174zM 107.603,193.823L 153.36,193.823L 153.36,148.066L 107.603,148.066zM 107.603,132.598L 153.36,132.598L 153.36,86.848L 107.603,86.848zM 236.52,193.823L 282.242,193.823L 282.242,148.066L 236.52,148.066zM 365.40,193.823L 411.155,193.823L 411.155,148.066L 365.40,148.066zM 365.40,255.05L 411.155,255.05L 411.155,209.319L 365.40,209.319zM 393.676,414.993l0.00-20.091 c 7.886-6.972, 12.886-17.154, 12.886-28.519c0.00-21.04-17.044-38.116-38.088-38.116 - c-21.069,0.00-38.114,17.076-38.114,38.116c0.00,11.365, 5.001,21.547, 12.885,28.519L 343.245,414.993 L 169.575,414.993 l0.00-20.091 - c 7.885-6.972, 12.885-17.154, 12.885-28.519c0.00-21.04-17.044-38.116-38.087-38.116c-21.07,0.00-38.114,17.076-38.114,38.116 - c0.00,11.365, 5.00,21.547, 12.884,28.519L 119.143,414.993 L 32.91,414.993 l0.00-415.021 l 447.103,0.00 L 480.013,414.993 L 393.676,414.993 z M 75.331,42.393L 75.331,307.647 l 363.134,0.00 - l 0.001-265.254L 75.331,42.393 zM 236.52,255.05L 282.242,255.05L 282.242,209.319L 236.52,209.319zM 300.972,255.05L 346.727,255.05L 346.727,209.319L 300.972,209.319zM 300.972,132.598L 346.727,132.598L 346.727,86.848L 300.972,86.848zM 300.972,193.823L 346.727,193.823L 346.727,148.066L 300.972,148.066z" /> -<glyph unicode="" d="M 317.874,207.586L 223.48,285.505L 223.48,240.826L 161.002,240.828L 161.002,174.352L 223.478,174.35L 223.478,129.682 zM 127.404,207.801c0.00,33.476, 14.616,63.534, 37.808,84.158L 32.002,336.244l0.00-260.247 L 224.50,12.002l0.00,84.27 - C 169.65,103.824, 127.404,150.875, 127.404,207.801zM 240.00,320.392c 15.104,0.00, 29.512-2.982, 42.674-8.377l 166.323,55.294L 240.50,436.634L 32.002,367.309l 165.772-55.11 - C 210.815,317.478, 225.066,320.392, 240.00,320.392zM 352.596,207.801c0.00-56.84-42.12-103.833-96.848-111.494l0.00-84.305 l 192.497,63.995L 448.245,336.244 l-133.391-44.345 - C 338.008,271.276, 352.596,241.244, 352.596,207.801z" /> -<glyph unicode="" d="M 32.002,75.997L 224.50,12.002L 224.50,272.249L 32.002,336.244 zM 240.50,436.634L 32.002,367.309L 240.50,297.995L 448.997,367.309 zM 255.748,12.002L 448.245,75.997L 448.245,336.244L 255.748,272.249 z" /> -<glyph unicode="" d="M 381.254,375.126c 11.729-16.323, 17.626-35.857, 17.626-58.604c0.00-23.444-5.932-42.296-17.78-56.524 - c-6.646-7.991-16.385-15.30-29.295-21.893c 19.581-7.107, 34.383-18.403, 44.349-33.856 - c 9.959-15.455, 14.956-34.229, 14.956-56.263c0.00-22.745-5.709-43.133-17.101-61.193 - c-7.229-11.979-16.293-22.063-27.188-30.225c-12.258-9.372-26.718-15.826-43.383-19.271 - c-16.664-3.508-34.728-5.213-54.244-5.213l-173.00,0.00 L 96.194,416.011 l 185.54,0.00 C 328.561,415.327, 361.734,401.689, 381.254,375.126z - M 172.782,349.338l0.00-84.655 l 93.312,0.00 c 16.665,0.00, 30.194,3.166, 40.59,9.496c 10.396,6.346, 15.609,17.581, 15.609,33.748 - c0.00,17.875-6.893,29.682-20.639,35.423c-11.854,3.987-26.969,5.988-45.366,5.988L 172.782,349.338 z M 172.782,201.115l0.00-102.344 l 93.22,0.00 - c 16.632,0.00, 29.604,2.229, 38.885,6.765c 16.813,8.317, 25.229,24.298, 25.229,47.914c0.00,19.983-8.161,33.698-24.479,41.147 - c-9.093,4.188-21.879,6.324-38.354,6.518L 172.782,201.115 z" /> -<glyph unicode="" d="M 448.146,103.733c-32.37,33.626-39.422,96.247-46.244,144.357C 391.786,319.403, 389.655,399.545, 288.00,410.034L 288.00,422.951 - c0.00,12.958-19.774,23.464-32.732,23.464c-12.957,0.00-31.266-10.506-31.266-23.464l0.00-12.935 - c-100.815-10.558-104.324-90.674-114.348-161.949c-6.768-48.132-13.766-110.76-45.87-144.402 - c-6.481-6.794-8.294-16.796-4.60-25.428c 3.698-8.639, 12.184-14.235, 21.576-14.235l 350.482,0.00 c 9.406,0.00, 17.907,5.619, 21.597,14.286 - C 456.516,86.938, 454.672,96.957, 448.146,103.733zM 256.00-14.555c 25.712,0.00, 46.557,20.845, 46.557,46.557l-93.113,0.00 C 209.443,6.29, 230.287-14.555, 256.00-14.555z" /> -<glyph unicode="" d="M 460.282,399.933c-29.559,29.429-80.832,26.523-110.294-3.051L 141.657,187.507 - c-21.036-21.129-23.084-57.451-1.914-78.236c 21.114-21.168, 57.359-19.016, 78.394,2.113l 129.454,130.282 - c 5.135,4.709, 5.525,12.354, 0.21,18.147c-4.96,5.409-15.472,5.629-19.813,1.268L 199.015,131.397l0.00,0.00 - c-12.636-12.629-25.909-14.955-38.576-2.518c-12.674,12.531-12.258,27.254, 0.345,39.916l0.00,0.00l 206.882,207.896l0.00,0.00l-0.04,0.037 - c 21.007,21.043, 50.964,23.467, 72.00,2.515c 20.731-20.977, 21.542-54.067, 0.265-75.111l 0.007,0.045L 186.923,49.795l 0.01-0.031 - c-28.166-26.053-75.066-31.572-106.799-0.541c-29.505,29.422-26.095,77.855, 0.506,107.701l 175.476,176.465 - c 2.717,2.805, 5.619,13.408-0.289,18.62c-5.189,4.579-15.311,5.955-18.934,2.314L 61.859,177.889 - c-43.236-45.451-41.512-112.49-3.464-150.205c 38.01-37.904, 106.534-40.826, 149.494,2.51L 461.10,284.58 - C 490.632,314.03, 489.853,370.50, 460.282,399.933z" /> -<glyph unicode="" d="M 256.023,463.354L 32.188,192.187L 160.536,192.187L 160.531-1.098L 351.492-1.098L 351.498,192.18L 479.813,192.18 z" /> -<glyph unicode="" d="M 496.124,223.978L 224.957,447.812L 224.957,319.464L 31.672,319.469L 31.672,128.508L 224.949,128.502L 224.949,0.188 z" /> -<glyph unicode="" d="M 15.544,223.978L 286.711,447.812L 286.711,319.464L 479.996,319.469L 479.996,128.508L 286.719,128.502L 286.719,0.188 z" /> -<glyph unicode="" d="M 255.977-15.256L 479.813,255.912L 351.463,255.912L 351.469,449.198L 160.507,449.198L 160.501,255.92L 32.188,255.92 z" /> -<glyph unicode="" d="M 395.786,207.949c-0.646,64.859, 52.894,95.965, 55.287,97.51c-30.085,44.022-76.946,50.053-93.647,50.749 - c-39.881,4.039-77.818-23.48-98.059-23.48c-20.189,0.00-51.423,22.884-84.50,22.281c-43.47-0.646-83.552-25.275-105.935-64.207 - c-45.164-78.371-11.565-194.472, 32.454-258.033c 21.51-31.111, 47.159-66.057, 80.835-64.808 - c 32.43,1.295, 44.693,20.983, 83.90,20.983c 39.208,0.00, 50.229-20.983, 84.549-20.339c 34.896,0.648, 57.006,31.707, 78.366,62.914 - c 24.702,36.094, 34.872,71.038, 35.472,72.832C 463.735,104.708, 396.461,130.479, 395.786,207.949z M 331.301,398.287 - c 17.874,21.685, 29.938,51.77, 26.647,81.783c-25.746-1.048-56.954-17.149-75.426-38.785 - c-16.575-19.194-31.083-49.826-27.194-79.24C 284.069,359.802, 313.408,376.65, 331.301,398.287z" /> -<glyph unicode="" d="M 432.00,320.00c-17.601,0.00-32.00-14.40-32.00-32.00l0.00-128.00 c0.00-17.60, 14.399-32.00, 32.00-32.00c 17.60,0.00, 32.00,14.40, 32.00,32.00L 464.00,288.00 C 464.00,305.60, 449.60,320.00, 432.00,320.00z - M 48.00,320.00c-17.601,0.00-32.00-14.40-32.00-32.00l0.00-128.00 c0.00-17.60, 14.399-32.00, 32.00-32.00c 17.60,0.00, 32.00,14.40, 32.00,32.00L 80.00,288.00 C 80.00,305.60, 65.599,320.00, 48.00,320.00z M 96.00,112.00 - c0.00-26.51, 21.49-48.00, 48.00-48.00l 16.00,0.00 l0.00-64.00 c0.00-17.60, 14.399-32.00, 32.00-32.00c 17.60,0.00, 32.00,14.40, 32.00,32.00l0.00,64.00 l 32.00,0.00 l0.00-64.00 c0.00-17.60, 14.40-32.00, 32.00-32.00 - c 17.599,0.00, 32.00,14.40, 32.00,32.00l0.00,64.00 l 16.00,0.00 c 26.51,0.00, 48.00,21.49, 48.00,48.00L 384.00,288.00 L 96.00,288.00 L 96.00,112.00 z M 299.299,435.253l 20.252,38.903 - c 1.016,1.951, 0.25,4.379-1.701,5.395c-1.951,1.016-4.379,0.25-5.396-1.701l-20.559-39.493C 275.797,444.581, 258.299,448.00, 240.00,448.00 - c-18.298,0.00-35.796-3.419-51.898-9.643L 167.544,477.849c-1.017,1.951-3.443,2.717-5.396,1.701 - c-1.952-1.016-2.717-3.443-1.701-5.395l 20.25-38.904c-45.314-20.509-78.119-63.792-83.81-115.252l 286.22,0.00 - C 377.42,371.461, 344.614,414.743, 299.299,435.253z M 176.00,344.80c-12.813,0.00-23.20,10.387-23.20,23.20s 10.387,23.20, 23.20,23.20 - c 12.813,0.00, 23.20-10.387, 23.20-23.20C 199.199,355.187, 188.813,344.80, 176.00,344.80z M 304.00,344.80c-12.813,0.00-23.201,10.387-23.201,23.20 - S 291.188,391.20, 304.00,391.20c 12.812,0.00, 23.198-10.387, 23.198-23.20S 316.813,344.80, 304.00,344.80z" /> -<glyph unicode="" d="M 32.74,415.823l0.00-64.651 L 480.00,351.172 L 480.00,415.823 L 32.74,415.823 z M 480.00,320.151L 32.74,320.151 l0.00-64.652 L 480.00,255.499 L 480.00,320.151 z M 480.00,223.831L 32.74,223.831 l0.00-64.667 L 480.00,159.164 - L 480.00,223.831 z M 479.854,127.831L 241.426,127.831 l0.00-64.667 l 238.428,0.00 L 479.854,127.831 z" /> -<glyph unicode="" d="M 32.741,415.823l0.00-64.651 L 480.00,351.172 L 480.00,415.823 L 32.741,415.823 z M 32.741,255.861L 480.00,255.861 l0.00,64.652 L 32.741,320.513 L 32.741,255.861 z M 32.741,159.164L 480.00,159.164 - l0.00,64.667 L 32.741,223.831 L 32.741,159.164 z M 32.887,63.164l 238.427,0.00 l0.00,64.668 L 32.887,127.832 L 32.887,63.164 z" /> -<glyph unicode="" d="M 32.37,415.823l0.00-64.651 l 447.26,0.00 L 479.63,415.823 L 32.37,415.823 z M 32.37,255.861l 447.26,0.00 l0.00,64.652 L 32.37,320.513 L 32.37,255.861 z M 32.37,158.99l 447.26,0.00 - l0.00,64.666 L 32.37,223.656 L 32.37,158.99 z M 136.786,63.164l 238.428,0.00 l0.00,64.668 L 136.786,127.832 L 136.786,63.164 z" /> -<glyph unicode="" d="M 55.773,415.998L 89.242,65.979L 179.998,156.734L 316.659,20.057L 451.689,155.088L 315.025,291.759L 405.758,382.491 z" /> -<glyph unicode="" d="M 451.689,415.998L 418.221,65.979L 327.465,156.734L 190.804,20.057L 55.773,155.088L 192.438,291.759L 101.705,382.491 z" /> -<glyph unicode="" d="M 55.773,28.153L 89.242,378.178L 179.998,287.422L 316.659,424.10L 451.689,289.069L 315.025,152.393L 405.758,61.661 z" /> -<glyph unicode="" d="M 451.689,28.153L 418.221,378.178L 327.465,287.422L 190.804,424.10L 55.773,289.069L 192.438,152.393L 101.705,61.661 z" /> -<glyph unicode="" d="M 255.50,479.00L 31.938,255.437L 159.688,255.437L 159.688-32.00L 351.313-32.00L 351.313,255.437L 479.063,255.437 z" /> -<glyph unicode="" d="M 142.056-32.649L-0.909,156.133L 88.021,223.45L 182.043,99.299L 418.531,479.002L 513.212,420.044L 233.86-32.649 - z" /> -<glyph unicode="" d="M 511.352,435.355L 467.354,479.351L 256.00,267.998L 44.646,479.351L 0.649,435.355L 212.003,224.00L 0.649,12.647L 44.646-31.351L 256.00,180.004L 467.354-31.351L 511.352,12.647L 299.997,224.00 - z" /> -<glyph unicode="" d="M 432.324,224.013c0.00,27.226, 16.741,48.712, 41.994,63.479c-4.563,15.178-10.563,29.739-17.998,43.431 - c-28.278-7.384-51.198,3.691-70.452,22.971c-19.254,19.228-25.15,42.149-17.741,70.453c-13.69,7.409-28.253,13.434-43.456,17.972 - c-14.767-25.254-41.456-41.996-68.685-41.996c-27.226,0.00-53.889,16.741-68.682,41.996c-15.204-4.539-29.74-10.563-43.456-17.972 - c 7.409-28.304, 1.512-51.225-17.742-70.453c-19.254-19.279-42.149-30.354-70.453-22.971c-7.409-13.692-13.434-28.253-17.972-43.431 - c 25.228-14.767, 41.996-36.252, 41.996-63.479c0.00-27.228-16.768-53.942-41.996-68.71c 4.539-15.177, 10.563-29.74, 17.972-43.43 - c 28.304,7.383, 51.199,1.488, 70.453-17.74c 19.254-19.28, 25.151-42.175, 17.742-70.454c 13.715-7.436, 28.251-13.459, 43.456-17.997 - c 14.793,25.228, 41.457,41.994, 68.682,41.994c 27.229,0.00, 53.918-16.767, 68.685-41.994c 15.203,4.538, 29.766,10.562, 43.456,17.997 - c-7.383,28.279-1.513,51.174, 17.741,70.454c 19.254,19.229, 42.174,30.327, 70.452,22.918c 7.436,13.692, 13.436,28.253, 17.998,43.482 - C 449.065,175.301, 432.324,196.785, 432.324,224.013z M 255.986,129.051c-52.428,0.00-94.936,42.508-94.936,94.962 - c0.00,52.43, 42.508,94.911, 94.936,94.911c 52.456,0.00, 94.938-42.481, 94.938-94.911C 350.924,171.559, 308.442,129.051, 255.986,129.051z" /> -<glyph unicode="" d="M 427.555,397.486L 84.457,397.486 l-28.806-54.838L 456.35,342.648 L 427.555,397.486zM 321.42,449.405L 189.754,449.405 l0.00-26.547 L 321.42,422.858 L 321.42,449.405 zM 114.156-1.405l 283.702,0.00 l 28.795,317.869L 85.348,316.464 L 114.156-1.405z M 322.633,288.831l 25.488,0.00 l0.00-261.495 l-25.488,0.00 L 322.633,288.831 z - M 242.424,288.831l 26.314,0.00 l0.00-261.495 l-26.314,0.00 L 242.424,288.831 z M 163.04,288.831l 26.328,0.00 l0.00-261.495 L 163.04,27.336 L 163.04,288.831 z" /> -<glyph unicode="" d="M 256.00,479.511C 114.885,479.511, 0.489,365.115, 0.489,224.00c0.00-141.114, 114.396-255.512, 255.511-255.512 - c 141.114,0.00, 255.512,114.397, 255.512,255.512C 511.512,365.115, 397.114,479.511, 256.00,479.511z M 256.00,127.719 - c-53.174,0.00-96.281,43.107-96.281,96.281c0.00,53.174, 43.106,96.281, 96.281,96.281c 53.173,0.00, 96.281-43.106, 96.281-96.281 - C 352.281,170.826, 309.173,127.719, 256.00,127.719z M 48.198,136.23C 36.447,164.014, 30.489,193.543, 30.489,224.00 - s 5.958,59.987, 17.709,87.77c 11.357,26.85, 27.621,50.97, 48.341,71.69c 0.377,0.377, 0.765,0.743, 1.145,1.118l 70.208-70.208 - c-23.534-22.95-38.173-54.98-38.173-90.37s 14.64-67.42, 38.173-90.37l-70.208-70.209c-0.38,0.375-0.767,0.74-1.145,1.118 - C 75.819,85.26, 59.555,109.38, 48.198,136.23z M 415.461,64.539c-0.446-0.446-0.902-0.878-1.352-1.32L 343.90,133.427 - c 23.655,22.964, 38.381,55.079, 38.381,90.573c0.00,35.494-14.726,67.608-38.38,90.572l 70.208,70.208 - c 0.449-0.441, 0.905-0.874, 1.352-1.32c 20.72-20.72, 36.984-44.84, 48.341-71.691c 11.751-27.783, 17.71-57.313, 17.71-87.77 - s-5.959-59.986-17.71-87.77C 452.445,109.38, 436.181,85.26, 415.461,64.539z" /> -<glyph unicode="" d="M 388.625,403.627l-13.938-81.237c-23.799,14.508-50.48,25.514-77.758,30.756l-9.889-66.753 - c 76.615-22.632, 114.924-50.506, 114.924-123.62c0.00-88.813-63.846-124.785-147.418-125.357l-9.291-67.92l-44.681,9.861l 8.708,60.941 - c-34.83,5.217-67.325,16.844-99.248,33.662l 12.77,80.094c 40.047-21.465, 71.386-31.924, 103.297-36.545l 11.613,80.666 - c-71.97,21.465-116.65,47.003-116.65,119.544c0.00,72.566, 49.326,117.831, 142.189,117.831c 1.738,0.00, 2.906,0.00, 4.646,0.00l 6.385,42.954 - l 44.107-9.863l-5.217-37.736C 340.453,425.688, 365.992,416.397, 388.625,403.627z M 255.131,357.792 - c-30.185,0.00-42.37-10.459-42.37-27.874c0.00-14.509, 8.708-23.204, 39.463-33.091l 8.708,60.965 - C 259.191,357.792, 256.869,357.792, 255.131,357.792z M 310.27,149.408c0.00,18.012-8.721,28.445-37.725,38.309l-11.029-71.945 - C 292.258,116.342, 310.27,127.945, 310.27,149.408z" /> -<glyph unicode="" d="M 128.00,447.998L 192.00,447.998L 192.00,383.998L 128.00,383.998zM 128.00,351.998L 192.00,351.998L 192.00,287.998L 128.00,287.998zM 128.00,255.998L 192.00,255.998L 192.00,191.998L 128.00,191.998zM 128.00,159.897L 192.00,159.897L 192.00,95.897L 128.00,95.897zM 128.00,64.002L 192.00,64.002L 192.00,0.002L 128.00,0.002zM 224.00,447.998L 288.00,447.998L 288.00,383.998L 224.00,383.998zM 224.00,351.998L 288.00,351.998L 288.00,287.998L 224.00,287.998zM 224.00,255.998L 288.00,255.998L 288.00,191.998L 224.00,191.998zM 224.00,159.897L 288.00,159.897L 288.00,95.897L 224.00,95.897zM 224.00,64.002L 288.00,64.002L 288.00,0.002L 224.00,0.002zM 320.00,447.998L 384.00,447.998L 384.00,383.998L 320.00,383.998zM 320.00,351.998L 384.00,351.998L 384.00,287.998L 320.00,287.998zM 320.00,255.998L 384.00,255.998L 384.00,191.998L 320.00,191.998zM 320.00,159.897L 384.00,159.897L 384.00,95.897L 320.00,95.897zM 320.00,64.002L 384.00,64.002L 384.00,0.002L 320.00,0.002z" /> -<glyph unicode="" d="M 160.00,352.00L 224.00,352.00L 224.00,288.00L 160.00,288.00zM 160.00,256.00L 224.00,256.00L 224.00,192.00L 160.00,192.00zM 160.00,160.00L 224.00,160.00L 224.00,96.00L 160.00,96.00zM 256.00,352.00L 320.00,352.00L 320.00,288.00L 256.00,288.00zM 256.00,256.00L 320.00,256.00L 320.00,192.00L 256.00,192.00zM 256.00,160.00L 320.00,160.00L 320.00,96.00L 256.00,96.00z" /> -<glyph unicode="" d="M 479.47,447.998L 128.002,447.998 l0.00-128.00 c-40.639,0.00-96.00,0.00-96.00,0.00L 32.002,0.53 l 351.994,0.00 L 383.996,128.002 l 95.474,0.00 L 479.47,447.998 z - M 319.996,64.002L 96.002,64.002 L 96.002,224.264 l 32.00,0.00 l0.00-96.262 l 191.994,0.00 C 319.996,102.986, 319.996,64.002, 319.996,64.002z M 415.996,192.002L 192.002,192.002 - L 192.002,351.998 l 223.994,0.00 L 415.996,192.002 z" /> -<glyph unicode="" d="M 509.249,56.123L 269.033,461.332c-3.088,5.49-9.051,8.531-15.301,7.53 - c-4.615-0.733-8.547-3.573-10.765-7.53L 2.752,56.123c-2.635-4.683-2.639-10.691,0.00-15.354c 2.676-4.724, 7.629-7.82, 13.023-7.82 - l 480.445,0.00 c 5.383,0.00, 10.354,3.097, 13.028,7.82C 511.885,45.432, 511.885,51.44, 509.249,56.123z M 255.969,57.917 - c-21.576,0.00-39.07,17.883-39.07,39.942c0.00,22.09, 17.494,39.972, 39.07,39.972c 21.562,0.00, 39.07-17.882, 39.07-39.972 - C 295.039,75.80, 277.53,57.917, 255.969,57.917z M 278.495,161.388l-45.381,0.00 c0.00,0.00-16.312,96.182-16.312,162.234 - c0.00,40.005, 4.77,60.375, 39.414,60.375c 26.641,0.00, 37.574-17.129, 37.574-58.226C 293.791,259.751, 278.495,161.388, 278.495,161.388z" /> -<glyph unicode="" d="M 256.00,478.473c-140.549,0.00-254.489-113.94-254.489-254.458c0.00-140.581, 113.94-254.488, 254.489-254.488 - s 254.488,113.907, 254.488,254.488C 510.488,364.533, 396.549,478.473, 256.00,478.473z M 304.791,336.772 - c0.00-66.021-26.296-174.384-26.296-174.384l-45.38,0.00 c0.00,0.00-26.312,106.182-26.312,172.234c0.00,40.005, 14.769,61.378, 49.413,61.378 - C 282.857,396.00, 304.791,377.868, 304.791,336.772z M 255.969,58.917c-21.576,0.00-39.07,17.883-39.07,39.942 - c0.00,22.09, 17.494,39.972, 39.07,39.972c 21.562,0.00, 39.07-17.882, 39.07-39.972C 295.039,76.80, 277.53,58.917, 255.969,58.917z" /> -<glyph unicode="" d="M 470.70,72.193l-2.688,2.688l 0.006,0.002L 360.505,182.408c 14.938,25.732, 23.612,55.564, 23.816,87.451 - c 0.626,97.615-77.986,177.243-175.599,177.857c-0.394,0.001-0.771,0.002-1.168,0.002 - c-97.06-0.006-176.063-78.391-176.688-175.598c-0.618-97.609, 77.999-177.236, 175.597-177.859 - c 0.389-0.002, 0.766-0.004, 1.155-0.004c 32.438,0.00, 62.846,8.79, 88.998,24.075l 107.415-107.433l 0.014,0.01l 2.688-2.688 - c 8.125-8.123, 21.293-8.114, 29.41,0.00l 34.562,34.557C 478.819,50.895, 478.822,64.07, 470.70,72.193z M 300.39,177.58 - c-24.834-24.67-57.78-38.252-92.768-38.252l-0.874,0.00 c-72.589,0.467-131.271,59.908-130.813,132.503 - c 0.465,72.128, 59.516,130.811, 131.626,130.815l 0.879-0.002c 35.168-0.22, 68.146-14.123, 92.852-39.148 - c 24.706-25.025, 38.188-58.178, 37.966-93.352C 339.031,235.128, 325.229,202.25, 300.39,177.58zM 128.503,287.997L 287.501,287.997L 287.501,256.203L 128.503,256.203z" /> -<glyph unicode=" " horiz-adv-x="256" /> -<glyph class="hidden" unicode="" d="M0,480L 512 -32L0 -32 z" horiz-adv-x="0" /> -</font></defs></svg> \ No newline at end of file diff --git a/lib/web/fonts/MUI-Icons/MUI-Icons.ttf b/lib/web/fonts/MUI-Icons/MUI-Icons.ttf deleted file mode 100644 index 533d70c5251f8..0000000000000 Binary files a/lib/web/fonts/MUI-Icons/MUI-Icons.ttf and /dev/null differ diff --git a/lib/web/fonts/UX-Icons/UX-Icons.eot b/lib/web/fonts/UX-Icons/UX-Icons.eot deleted file mode 100644 index 296bf3c19aa1f..0000000000000 Binary files a/lib/web/fonts/UX-Icons/UX-Icons.eot and /dev/null differ diff --git a/lib/web/fonts/UX-Icons/UX-Icons.svg b/lib/web/fonts/UX-Icons/UX-Icons.svg deleted file mode 100644 index 85a68c310325e..0000000000000 --- a/lib/web/fonts/UX-Icons/UX-Icons.svg +++ /dev/null @@ -1,68 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > -<svg xmlns="http://www.w3.org/2000/svg"> -<metadata>Generated by IcoMoon</metadata> -<defs> -<font id="icomoon" horiz-adv-x="1024"> -<font-face units-per-em="1024" ascent="960" descent="-64" /> -<missing-glyph horiz-adv-x="1024" /> -<glyph unicode=" " d="" horiz-adv-x="512" /> -<glyph unicode="" d="M709.921 789.454c8.139-32.295 8.927-34.974 8.192-68.162-0.263-12.813-7.772-71.943-5.724-90.112 1.628-14.966 5.461-16.174 11.448-28.514 10.398-21.425 6.984-51.095 2.941-72.678-2.206-11.868-6.827-28.725-13.916-38.387-7.667-10.66-23.211-10.713-30.142-23.158-9.872-17.854-4.306-43.008-10.503-62.385-7.142-21.898-25.101-23.421-26.466-52.145 8.822-1.155 17.592-2.468 26.466-3.623 8.822-18.59 25.049-55.874 41.59-67.059 13.863-3.728 27.727-7.457 41.59-11.185 48.627-19.64 102.558-43.061 151.237-63.33 44.373-18.432 97.411-24.996 113.48-70.84 0-31.035 2.941-104.501 2.153-145.25h-965.553c-0.893 40.697 2.153 114.215 2.153 145.25 15.964 45.844 69.002 52.408 113.375 70.84 48.679 20.27 102.61 43.691 151.237 63.33 13.811 3.728 27.674 7.457 41.59 11.185 16.489 11.185 32.715 48.522 41.538 67.059l19.692 4.621c-4.464 24.576-19.85 26.466-26.256 43.743-2.521 26.099-5.041 52.145-7.509 78.192 0.053-1.155-18.117 3.361-20.48 4.779-25.731 15.806-26.204 80.24-28.725 107.021-1.103 12.183 16.174 22.265 11.343 44.636-28.094 131.44 12.183 192.88 75.881 213.307 44.216 17.749 126.871 50.465 203.855 3.728l19.167-17.487 30.93-5.251c15.491-8.77 25.416-38.124 25.416-38.124z" horiz-adv-x="1090" /> -<glyph unicode="" d="M529.203 62.008l-468.465 628.209h936.931l-468.465-628.209z" horiz-adv-x="1085" /> -<glyph unicode="" d="M976.793-33.858h-910.388v910.388h910.388v-910.388zM912.622 812.359h-782.046v-782.088h782.046v782.088zM221.432 125.348h152.876v372.033h-152.876v-372.033zM466.323 127.914h350.932v366.53h-350.932v-366.53zM221.432 587.659h595.865v147.125h-595.865v-147.125z" horiz-adv-x="1034" /> -<glyph unicode="" d="M264.319 639.317c75.685 0 136.98 61.259 136.98 136.944 0 75.649-61.295 136.98-136.98 136.98s-137.017-61.331-137.017-136.98c0-75.649 61.331-136.944 137.017-136.944zM448.929 577.297c-28.962 28.926-63.325 46.252-187.655 46.252s-157.859-18.776-185.335-46.252c-27.44-27.44-18.196-320.43-18.196-320.43l60.824 144.411 38.241-430.334 110.23 220.278 102.907-220.278 36.393 430.334 60.824-144.411c-0.036 0 10.693 291.468-18.233 320.43z" horiz-adv-x="489" /> -<glyph unicode="" d="M680.975 874.42c-337.523 0-610.976-273.515-611.038-610.976 0.122-37.72 1.039-251.812 1.039-251.812h1219.997c0 0 0.978 239.219 1.039 251.812-0.183 337.523-273.637 610.976-611.038 610.976zM737.708 750.317c31.117-3.607 61.379-10.271 90.418-19.624l-19.93-61.685c-25.004 8.070-51.169 13.939-78.191 16.995l7.703 64.313zM270.091 274.998h-64.864c0 31.423 3.118 62.235 8.803 92.007l63.702-12.349c-5.135-25.799-7.642-52.392-7.642-79.658zM305.855 443.729l-59.178 26.288c12.655 28.489 28 55.449 45.79 80.636l52.942-37.475c-15.284-21.825-28.611-45.056-39.554-69.449zM407.46 582.993l-43.405 48.113c22.925 20.541 47.807 39.187 74.462 54.96l33.318-55.571c-22.987-13.755-44.567-29.65-64.374-47.501zM536.943 730.693c29.039 9.292 59.178 16.017 90.418 19.624l7.581-64.313c-26.838-3.057-53.003-8.926-78.13-16.995l-19.869 61.685zM761.673 146.616l-152.897-27.205-38.881 150.452 395.172 404.22-203.394-527.467zM1019.476 513.177l52.942 37.414c17.79-25.187 33.257-52.148 45.851-80.636l-59.178-26.288c-10.943 24.454-24.209 47.685-39.615 69.51zM1094.916 274.998c0 27.266-2.69 53.859-7.703 79.658l63.702 12.349c5.808-29.834 8.803-60.645 8.803-92.007h-64.802zM646.006 177.489c26.777-17.056 62.174-9.415 79.291 17.24 17.118 26.593 9.292 62.051-17.301 79.108-26.655 17.24-62.051 9.354-79.23-17.362-17.118-26.349-9.476-61.99 17.24-78.986z" horiz-adv-x="1376" /> -<glyph unicode="" d="M24.097 834.683h972.827v-111.922l-410.504-412.792v-238.366l-171.447-87.505v325.871l-390.875 415.877v108.837z" /> -<glyph unicode="" d="M454.495 899.249l-402.697-240.513v-457.026l104.632-60.727v457.049l298.157 178.728 299.698-179.142-0.138-455.922 103.528 60.013v457.026l-403.18 240.513zM507.766 617.868v-534.344l-53.271-32.124-53.34 32.262v533.792l-138.090-83.853v-456.934l191.453-115.516 193.087 116.322v456.451l-139.839 83.945z" horiz-adv-x="903" /> -<glyph unicode="" d="M870.821 216.311c-64.195 65.89-78.231 188.772-91.738 283.159-20.074 139.937-24.259 297.089-226.008 317.693v25.318c0 25.424-39.195 46.028-64.937 46.028s-62.024-20.551-62.024-46.028v-25.371c-200.054-20.816-206.993-177.914-226.855-317.693-13.453-94.439-27.331-217.268-91.049-283.264-12.818-13.348-16.473-32.998-9.11-49.947 7.362-16.843 24.153-27.913 42.797-27.913h695.343c18.75 0 35.593 11.070 42.903 28.019s3.655 36.653-9.322 50zM489.569-15.735c51.060 0 92.373 40.837 92.373 91.367h-184.694c-0.053-50.53 41.314-91.367 92.32-91.367z" horiz-adv-x="989" /> -<glyph unicode="" d="M252.137 794.92l-160.070-92.393 378.042-218.205 160.023 92.393-377.996 218.205zM845.638 701.085l-377.996 218.252-145.222-83.828 377.996-218.205 145.222 83.782zM502.784 421.998v-433.664l376.832 217.507v433.711l-376.832-217.553zM55.668 205.888l376.785-217.507v436.503l-376.785 217.46v-436.457z" horiz-adv-x="954" /> -<glyph unicode="" d="M59.153 413.966l164.053-38.141v303.902l-164.053-38.141v-227.621zM1122.198 888.995l-837.712-194.959v-335.978l140.328-376.832 151.712 57.45-104.049 279.113 649.668-151.18v722.385z" horiz-adv-x="1170" /> -<glyph unicode="" d="M736.707-33.086h207.134v322.703h-207.134v-322.703zM399.646-33.086h207.134v946.793h-207.134v-946.793zM62.673-33.042h207.134v634.704h-207.134v-634.704z" horiz-adv-x="991" /> -<glyph unicode="" d="M426.502 335.631c-15.866 13.512-42.796 25.753-80.79 36.723v-198.774c11.535 1.459 23.729 4.331 36.299 8.851 12.618 4.426 23.87 10.829 33.804 19.068 9.981 8.427 18.173 18.55 24.529 30.649 6.638 12.006 9.651 26.365 9.651 42.89 0.047 26.836-7.721 47.222-23.493 60.593zM576.736 211.292c-7.109-23.117-19.774-45.762-38.135-67.749-18.503-22.175-43.079-41.855-74.010-58.992-30.885-17.373-70.432-27.683-118.878-31.12v-88.088h-57.014v88.088c-72.080 5.603-128.483 29.237-169.113 71.374-40.536 42.090-63.935 104.095-70.432 185.544h136.251c-0.753-39.359 8.992-70.479 28.86-93.266 20.15-22.74 44.774-37.335 74.434-43.455v216.523c-3.060 1.318-7.486 2.919-12.994 4.567-5.508 1.789-11.393 3.343-17.938 4.708-23.776 6.827-47.175 15.019-70.291 24.294-23.493 9.369-44.114 21.704-62.523 37.335-18.456 15.584-33.098 34.84-43.879 57.956-11.111 23.211-16.478 51.977-16.478 86.487 0 35.31 6.168 66.336 18.785 93.313 12.665 26.836 29.143 49.529 49.858 67.702 20.621 18.314 44.303 32.58 71.468 42.419 27.071 10.122 55.037 16.149 83.992 18.314v79.66h57.014v-79.66c29.143-3.531 56.308-10.169 81.638-20.292 25.423-10.028 47.787-23.729 67.137-41.478 19.585-17.514 35.357-39.453 47.457-65.771 12.288-26.13 19.35-57.109 21.28-93.172h-137.287c-0.518 27.636-8.616 51.082-23.917 70.432-15.725 19.303-34.275 29.002-56.308 29.002v-183.331c7.862-2.072 15.631-4.143 23.729-6.12 8.098-2.072 16.525-4.567 25.565-7.297 47.645-13.983 84.415-31.12 110.168-51.318 25.8-20.292 44.726-41.666 56.92-63.653 12.335-22.175 19.633-44.256 21.704-66.336 2.448-22.081 3.531-41.713 3.531-59.039 0.047-15.207-3.531-34.416-10.593-57.579zM228.905 684.733c-8.38-7.156-15.113-16.196-19.962-26.883-4.802-10.781-7.062-23.352-7.062-37.759 0-22.834 6.733-40.536 20.103-52.824 13.653-12.618 35.734-22.552 66.713-30.131v168.831c-10.829 0-21.516-1.695-31.826-5.226-10.216-3.437-19.633-8.851-27.966-16.007z" horiz-adv-x="659" /> -<glyph unicode="" d="M555.139 926.506c-218.775 71.601-457.062-40.29-532.231-250.028-75.227-209.681 41.211-437.665 259.928-509.208 218.717-71.601 457.004 40.348 532.231 250.028s-41.211 437.665-259.928 509.208zM320.076 271.103c-158.915 52.089-243.467 217.681-188.903 369.978 54.679 152.296 227.754 233.625 386.669 181.593s243.409-217.624 188.788-369.92c-54.622-152.296-227.696-233.567-386.554-181.65zM638.482 262.354l358.927-349.602 24.807 69.241 24.865 69.241-310.348 302.29z" horiz-adv-x="1109" /> -<glyph unicode="" d="M1098.281 862.698c19.777 3.723 34.901 21.232 34.901 42.347-0.058 23.791-19.196 43.103-42.812 43.103h-900.508c-23.675 0-42.754-19.312-42.754-43.103 0-21.057 15.007-38.566 34.843-42.347l-181.951-354.421v-68.988c0-30.946 32.516-56.016 72.594-56.016 13.437 0 26.001 2.908 36.821 7.795v-466.919h1061.286v466.919c10.878-4.944 23.326-7.795 36.879-7.795 40.078 0 72.594 25.071 72.594 56.016v68.988l-181.893 354.421zM214.758 383.273c-38.217 0-69.221 25.071-69.221 56.016v6.457h-0.349v62.531l137.162 353.665h109.648l-107.961-353.665v-68.988c0 0 0 0 0 0 0-30.946-31.004-56.016-69.279-56.016zM498.447 383.273c-38.217 0-69.221 25.071-69.221 56.016v68.988l57.354 353.665h109.241l-28.095-353.665v-68.93c-0.058-31.004-31.004-56.075-69.279-56.075zM782.077 383.273c-38.217 0-69.162 25.071-69.162 56.016v68.988l-28.154 353.665h108.892l57.296-353.665v-68.988c0-0.931 0.175-1.92 0.233-2.792-1.803-29.666-32.051-53.224-69.104-53.224zM1134.637 439.289c0-30.946-31.004-56.016-69.221-56.016s-69.162 25.071-69.162 56.016v68.988l-108.019 353.665h109.59l137.22-353.665v-62.473h-0.349v-6.515h-0.058z" horiz-adv-x="1280" /> -<glyph unicode="" d="M1024 380.306v116.547l-141.218 46.117-33.219 80.36 63.981 135.383-82.407 82.407-15.458-7.831-117.008-59.477-80.309 33.321-50.57 141.014h-116.496l-5.374-16.533-40.743-124.686-80.258-33.321-135.537 63.981-82.356-82.407 7.882-15.407 59.323-117.059-33.219-80.258-141.014-50.519v-116.547l141.218-46.066 33.219-80.36-63.878-135.383 82.254-82.407 15.458 7.831 117.008 59.425 80.36-33.27 50.468-140.963h116.496l5.426 16.43 40.692 124.737 80.309 33.27 135.383-63.981 82.458 82.407-7.882 15.458-59.374 116.957 33.27 80.36 141.116 50.468zM512 272.92c-90.136 0-163.177 73.040-163.177 163.177s73.040 163.177 163.177 163.177c90.187 0 163.177-73.040 163.177-163.177s-72.989-163.177-163.177-163.177z" /> -<glyph unicode="" d="M944.97 619.106c-97.861 0-177.522-79.581-177.522-177.443 0-97.94 79.66-177.679 177.522-177.679 98.019 0 177.679 79.739 177.679 177.679 0 97.861-79.66 177.443-177.679 177.443zM944.97 948.148c-470.712 0-944.97-512-944.97-512s474.258-512 944.97-512c470.949 0 945.128 512 945.128 512s-474.179 512-945.128 512zM944.97 79.292c-200.057 0-362.292 162.078-362.292 362.45 0 200.057 162.236 362.292 362.292 362.292 200.214 0 362.45-162.236 362.45-362.292 0-200.451-162.236-362.45-362.45-362.45z" horiz-adv-x="1890" /> -<glyph unicode="" d="M1020.032 382.593v116.045l-16.41 5.376-124.237 40.525-33.152 80.102 63.718 134.784-82.048 82.125-15.411-7.808-116.531-59.213-80.077 33.178-50.278 140.442h-116.096l-45.875-140.698-80-33.126-134.963 63.744-82.022-82.074 7.834-15.334 59.162-116.608-33.126-80.026-140.518-50.253v-116.147l16.435-5.325 124.288-40.576 33.075-80-63.693-134.886 82.048-82.099 131.942 66.97 80.026-33.152 50.304-140.39h116.096l5.35 16.41 40.55 124.237 80.077 33.178 134.886-63.718 82.074 82.074-7.834 15.386-59.213 116.582 33.203 80.026 140.416 50.253zM510.003 275.559c-89.754 0-162.509 72.832-162.509 162.611 0 89.754 72.755 162.483 162.509 162.483 89.83 0 162.509-72.73 162.509-162.483 0.026-89.805-72.653-162.611-162.509-162.611z" /> -<glyph unicode="" d="M509.978 893.722l-509.978-509.926 95.949-95.949 414.106 413.978 413.875-413.978 95.949 95.898-509.901 509.978zM146.253 259.585v-335.437h259.917v304.819h207.514v-304.819h259.917v335.488l-363.622 363.597-363.725-363.648z" /> -<glyph unicode="" d="M0 211.738l498.278-287.59v421.402l-498.278 287.667v-421.478zM894.464 723.662v-44.262c0-32.819-62.797-59.418-140.365-59.418-77.466 0-140.262 26.598-140.262 59.418v73.216h0.435c4.71-30.925 65.408-55.475 139.853-55.475 77.568 0 140.365 26.624 140.365 59.29 0 32.845-62.797 59.366-140.365 59.366-6.195 0-12.262-0.205-18.202-0.563l-90.317 52.147v-55.706c0-32.819-62.72-59.392-140.262-59.392-48.691 0-91.597 10.496-116.813 26.47-3.584 3.712-7.987 7.245-13.312 10.598-6.579 6.861-10.24 14.387-10.24 22.323v53.939l-87.322-50.381c-6.272 0.307-12.646 0.614-19.123 0.614-77.491 0-140.314-26.522-140.314-59.366 0-32.691 62.822-59.29 140.314-59.29 74.445 0 135.219 24.525 139.93 55.475h0.384v-73.216c0-32.819-62.746-59.418-140.314-59.418-77.491 0-140.314 26.598-140.314 59.418v43.622l-108.083-62.31 499.994-288.563 496.691 286.694-112.358 64.768zM646.784 540.135c0-32.794-62.874-59.315-140.365-59.315s-140.339 26.522-140.339 59.315v73.267h0.41c4.762-30.95 65.459-55.475 139.93-55.475s135.142 24.525 139.904 55.475h0.486v-73.267zM525.645 341.914v-417.766l498.355 287.718v417.766l-498.355-287.718zM505.318 829.492c77.542 0 140.262 26.547 140.262 59.315s-62.72 59.315-140.262 59.315c-77.491 0-140.339-26.573-140.339-59.315-0.026-32.768 62.822-59.315 140.339-59.315z" /> -<glyph unicode="" d="M287.002 466.484c0.205-0.23 0.461-0.486 0.691-0.717l103.347-103.373 36.045 36.045-56.55 56.499 90.266 90.189 11.904-1.28c3.046-0.307 6.093-0.538 9.19-0.538 6.246 0 12.314 0.768 18.253 2.125l-66.381 66.381c-1.357 1.382-2.765 2.611-4.173 3.814 20.454 73.6 1.766 155.725-56.038 213.555-57.421 57.421-138.803 76.237-211.968 56.525l123.955-123.981-32.563-121.446-121.395-32.589-124.032 124.006c-19.712-73.19-0.896-154.573 56.525-212.019 60.262-60.288 147.021-77.952 222.925-53.197zM653.235 392.346c-1.997-8.909-2.509-18.202-1.459-27.546l1.306-11.93-90.189-90.189-56.55 56.55-36.070-36.122 327.219-327.194c20.198-20.173 46.618-30.259 73.062-30.259s52.915 10.086 73.037 30.259c40.346 40.32 40.346 105.728 0 146.074l-290.355 290.355zM905.907-10.214l-51.866-13.875-42.112 42.112 13.901 51.891 51.866 13.926 42.112-42.138-13.901-51.917zM506.701 354.049l56.576-56.576 64.128 64.154c-3.482 31.334 6.707 63.821 30.669 87.808 24.013 23.962 56.474 34.176 87.808 30.72l280.397 280.346-157.056 157.056-280.448-280.397c3.482-31.258-6.682-63.821-30.669-87.782-24.013-23.987-56.525-34.176-87.808-30.643l-64.102-64.205 56.499-56.422-277.043-277.12-10.138 10.138-53.248-42.829-89.421-141.312 22.835-22.835 141.312 89.421 42.803 53.222-10.138 10.138 277.043 277.12z" /> -<glyph unicode="" d="M517.99 948.148c-279.398 0-505.882-226.534-505.882-505.958s226.483-505.958 505.882-505.958c279.501 0 506.010 226.534 506.010 505.958s-226.509 505.958-506.010 505.958zM614.835 136.295v274.56h181.53l-278.272 337.203-278.349-337.203h181.555v-274.56z" /> -<glyph unicode="" d="M512.794 948.148c-283.187 0-512.794-229.581-512.794-512.794 0-283.187 229.606-512.794 512.794-512.794s512.794 229.632 512.794 512.794c0 283.213-229.581 512.794-512.794 512.794zM512.794-23.065c-253.158 0-458.394 205.261-458.394 458.368 0 253.158 205.261 458.394 458.394 458.394 253.184 0 458.394-205.235 458.394-458.394 0.026-253.107-205.21-458.368-458.394-458.368zM760.013 322.535l30.387 38.4-265.6 206.413-20.787 1.613-259.226-208.026 28.826-39.987 236.8 177.613z" /> -<glyph unicode="" d="M512.794 948.148c-283.187 0-512.794-229.581-512.794-512.794 0-283.187 229.606-512.794 512.794-512.794s512.794 229.606 512.794 512.794c0 283.213-229.581 512.794-512.794 512.794zM512.794-23.065c-253.158 0-458.394 205.261-458.394 458.394 0 253.158 205.261 458.394 458.394 458.394 253.184 0 458.394-205.235 458.394-458.394 0.026-253.133-205.21-458.394-458.394-458.394zM265.6 493.748l-30.387-38.4 265.574-206.387 20.813-1.613 259.2 208-28.8 39.987-236.8-177.587z" /> -<glyph unicode="" d="M259.2 948.148h214.323v-214.323h-214.323v214.323zM259.2 678.273h214.323v-214.349h-214.323v214.349zM259.2 408.372h214.323v-214.349h-214.323v214.349zM259.2 138.497h214.323v-214.349h-214.323v214.349zM549.325 948.148h214.323v-214.323h-214.323v214.323zM549.325 678.273h214.323v-214.349h-214.323v214.349zM549.325 408.372h214.323v-214.349h-214.323v214.349zM549.325 138.497h214.323v-214.349h-214.323v214.349z" /> -<glyph unicode="" d="M860.058 763.086v-272l-430.029 269.158-1.894-253.491-424.371 249.754-3.763-647.834 426.24 241.28-5.606-239.437 439.424 252.16v-259.635h163.942v660.045z" /> -<glyph unicode="" d="M163.942 103.041v271.974l430.029-269.133 1.894 253.491 424.397-249.754 3.738 647.834-426.24-241.28 5.606 239.437-439.424-252.16v259.635h-163.942v-660.045z" /> -<glyph unicode="" d="M505.704 907.15c-260.096-3.489-468.158-217.202-464.706-477.336 3.489-259.982 217.202-468.12 477.298-464.631s468.158 217.202 464.706 477.336c-3.413 260.058-217.202 468.12-477.298 464.631zM557.928 750.175c47.863 0 62.009-27.762 62.009-59.544 0-39.671-31.782-76.383-86.016-76.383-45.359 0-66.901 22.831-65.65 60.53 0 31.782 26.624 75.435 89.657 75.435zM435.162 141.767c-32.73 0-56.661 19.873-33.792 107.217l37.547 154.814c6.485 24.841 7.585 34.778 0 34.778-9.785 0-52.262-17.143-77.407-34.057l-16.346 26.776c79.607 66.446 171.16 105.472 210.375 105.472 32.73 0 38.153-38.722 21.807-98.266l-43.008-162.816c-7.585-28.786-4.286-38.722 3.262-38.722 9.785 0 41.984 11.871 73.614 36.75l18.47-24.841c-77.369-77.369-161.792-107.179-194.56-107.179z" /> -<glyph unicode="" d="M591.986 500.129h-16.005v192.019c0 105.851-86.13 192.019-192.019 192.019h-128c-105.851 0-192.019-86.13-192.019-192.019v-192.019h-16.005c-26.396 0-48.014-21.618-48.014-48.014v-479.991c0-26.396 21.618-48.014 48.014-48.014h544.009c26.396 0 48.014 21.618 48.014 48.014v479.991c0 26.396-21.618 48.014-48.014 48.014zM384 52.148h-128l27.838 139.188c-16.801 11.529-27.838 30.872-27.838 52.793 0 35.347 28.672 64.019 64.019 64.019s64.019-28.672 64.019-64.019c0-21.921-11.036-41.263-27.838-52.793l27.838-139.188zM448.019 500.129h-256v192.019c0 35.271 28.71 64.019 64.019 64.019h128c35.271 0 64.019-28.71 64.019-64.019v-192.019z" /> -<glyph unicode="" d="M870.4 630.708h-194.56v-143.36h153.6v-215.040h-634.88v215.040h215.040v-112.64l204.8 184.32-204.8 184.32v-112.64h-256c-56.51 0-102.4-45.815-102.4-102.4v-296.96c0-56.51 45.89-102.4 102.4-102.4h716.8c56.585 0 102.4 45.89 102.4 102.4v296.96c0 56.585-45.815 102.4-102.4 102.4z" /> -<glyph unicode="" d="M991.991 564.148h-351.991v351.991c0 17.673-14.336 32.009-32.009 32.009h-192.019c-17.673 0-32.009-14.336-32.009-32.009v-351.991h-351.991c-17.673 0-32.009-14.336-32.009-32.009v-192.019c0-17.673 14.336-32.009 32.009-32.009h351.991v-351.991c0-17.673 14.336-32.009 32.009-32.009h192.019c17.673 0 32.009 14.336 32.009 32.009v351.991h351.991c17.673 0 32.009 14.336 32.009 32.009v192.019c0 17.673-14.336 32.009-32.009 32.009z" /> -<glyph unicode="" d="M505.704 907.15c-260.096-3.489-468.158-217.126-464.706-477.298 3.489-260.21 217.202-468.158 477.298-464.744 260.134 3.489 468.233 217.202 464.706 477.298-3.489 260.21-217.202 468.233-477.298 464.744zM506.577 845.748c70.163 0.986 136.382-15.853 194.56-46.118l-63.374-105.662c-38.002 18.47-80.631 28.937-125.762 28.937-45.056 0-87.723-10.43-125.687-28.975l-63.336 105.624c54.993 28.672 117.343 45.321 183.599 46.232zM254.255 310.461l-105.586-63.298c-28.672 54.955-45.321 117.305-46.194 183.486-0.986 70.201 15.853 136.457 46.118 194.56l105.624-63.45c-18.546-37.926-28.975-80.555-28.975-125.649 0-45.056 10.43-87.723 28.975-125.687zM517.461 26.586c-70.163-0.986-136.457 15.853-194.56 46.118l63.374 105.662c38.002-18.546 80.631-28.975 125.687-28.975 45.094 0 87.761 10.392 125.687 28.937l63.336-105.586c-54.993-28.634-117.305-45.246-183.561-46.194zM512 210.906c-124.397 0-225.242 100.883-225.242 225.242 0 124.397 100.883 225.28 225.242 225.28 124.473 0 225.28-100.883 225.28-225.28s-100.807-225.242-225.28-225.242zM769.745 310.461c18.546 38.002 28.975 80.631 28.975 125.687 0 45.094-10.43 87.723-28.975 125.687l105.586 63.374c28.672-54.993 45.359-117.305 46.232-183.561 0.91-70.201-15.929-136.457-46.194-194.56l-105.624 63.336z" /> -<glyph unicode="" d="M906.126 812.335v0c-91.174 75.89-202.487 113.171-312.548 113.057-127.014 0.038-253.611-49.683-348.16-145.636l-95.004 79.265-1.593-305.342 300.184 56.282-99.442 82.944c67.546 64.247 155.269 97.204 244.015 97.28 79.948-0.038 159.782-26.7 226.114-81.806 84.347-70.125 127.659-170.629 127.772-272.46-0.038-14.715-0.948-29.431-2.769-44.070l137.519 26.283c0.19 5.954 0.303 11.871 0.303 17.787 0.152 140.098-60.151 279.78-176.431 376.415zM839.035 181.172c-67.736-65.498-156.255-99.025-245.912-99.1-79.986 0.038-159.82 26.738-226.114 81.806-84.347 70.125-127.697 170.629-127.772 272.498 0 16.839 1.252 33.716 3.679 50.366l-138.164-25.941c-0.379-8.116-0.683-16.346-0.683-24.462-0.114-140.174 60.226-279.817 176.545-376.491 91.136-75.852 202.411-113.057 312.51-112.981h0.341c127.924 0 255.241 50.441 349.943 147.759l90.795-75.207 0.569 305.38-299.956-57.344 104.183-86.281z" horiz-adv-x="1176" /> -<glyph unicode="" d="M593.351 926.416c-270.753 0-490.268-219.477-490.268-490.231s219.515-490.268 490.268-490.268 490.231 219.515 490.231 490.268c0 270.753-219.477 490.231-490.231 490.231zM828.947 264.495l-72.363-72.363-162.095 162.133-164.902-164.902-73.121 73.121 164.902 164.902-161.678 161.678 72.363 72.325 161.602-161.678 165.774 165.736 73.121-73.083-165.774-165.736 162.171-162.133z" horiz-adv-x="1176" /> -<glyph unicode="" d="M254.976 272.308v267.264h103.424l-179.2 203.776-179.2-203.776h103.424v-308.224c0-56.51 45.815-102.4 102.4-102.4h459.776l-131.186 143.36h-279.438zM920.538 332.724v308.224c0 56.51-45.89 102.4-102.4 102.4h-459.738l131.11-143.36h279.514v-267.264h-103.424l179.2-203.776 179.2 203.776h-103.462z" /> -<glyph unicode="" d="M768 884.129h-128c-105.851 0-192.019-86.13-192.019-192.019v-192.019h-400.005c-26.396 0-48.014-21.618-48.014-48.014v-479.991c0-26.396 21.618-48.014 48.014-48.014h544.009c26.396 0 48.014 21.618 48.014 48.014v479.991c0 26.396-21.618 48.014-48.014 48.014h-16.005v192.019c0 35.271 28.71 64.019 64.019 64.019h128c35.271 0 64.019-28.71 64.019-64.019v-192.019h128v192.019c0 105.851-86.13 192.019-192.019 192.019zM384 52.148h-128l27.838 139.188c-16.801 11.529-27.838 30.872-27.838 52.793 0 35.347 28.672 64.019 64.019 64.019s64.019-28.672 64.019-64.019c0-21.921-11.036-41.263-27.838-52.793l27.838-139.188z" /> -<glyph unicode="" d="M593.351 948.148l-593.351-1023.962h1186.74l-593.351 1023.962zM653.236 48.697h-125.421v121.211h125.421v-121.211zM622.175 219.819h-62.502l-34.816 288.313v156.748h131.3v-156.748l-33.982-288.313z" horiz-adv-x="1176" /> -<glyph unicode="" d="M0 436.148l512-512v320.019h512v384h-512v320.019z" /> -<glyph unicode="" d="M1024 436.148l-512 512v-320.019h-512v-384h512v-320.019z" /> -<glyph unicode="" d="M402.735 801.413l-320.019-320.019c-24.993-24.993-24.993-65.498 0-90.491l320.019-320.019c24.993-24.993 65.498-24.993 90.491 0s24.993 65.498 0 90.491l-210.754 210.754h613.49c35.347 0 64.019 28.634 64.019 64.019s-28.672 64.019-64.019 64.019h-613.49l210.754 210.754c12.478 12.478 18.735 28.862 18.735 45.246s-6.258 32.768-18.735 45.246c-24.993 24.993-65.498 24.993-90.491 0z" /> -<glyph unicode="" d="M507.259 369.626h-102.059v-101.717h102.059v101.717zM650.885 233.434h-101.945v-101.717h101.945v101.717zM507.259 233.434h-102.059v-101.717h102.059v101.717zM507.259 505.818h-102.059v-101.679h102.059v101.679zM843.131 704.057c23.4 0 42.287 18.887 42.287 42.174v145.408c0 23.324-18.887 42.174-42.287 42.174s-42.325-18.849-42.325-42.174v-145.408c0.038-23.324 18.925-42.174 42.325-42.174zM343.419 704.057c23.362 0 42.249 18.887 42.249 42.174v145.408c0 23.324-18.887 42.174-42.249 42.174-23.4 0-42.325-18.849-42.325-42.174v-145.408c0-23.324 18.925-42.174 42.325-42.174zM363.444 369.626h-102.059v-101.717h102.059v101.717zM363.444 233.434h-102.059v-101.717h102.059v101.717zM650.885 369.626h-101.945v-101.717h101.945v101.717zM938.325 369.626h-102.059v-101.717h102.059v101.717zM938.325 505.818h-102.059v-101.679h102.059v101.679zM899.337 863.763v-46.914c17.598-15.474 28.71-38.153 28.71-63.412 0-46.801-37.964-84.764-84.916-84.764s-84.954 37.964-84.954 84.764c0 25.259 11.15 47.938 28.71 63.412v46.914h-387.262v-46.914c17.56-15.474 28.71-38.153 28.71-63.412 0-46.801-38.002-84.764-84.916-84.764s-84.954 37.964-84.954 84.764c0 25.259 11.15 47.938 28.71 63.412v46.914h-192.322v-925.279h997.035v925.279h-192.512zM999.234 32.844h-809.832v589.938h809.832v-589.938zM650.885 505.818h-101.945v-101.679h101.945v101.679zM794.624 505.818h-101.983v-101.679h101.983v101.679zM794.624 233.434h-101.983v-101.717h101.983v101.717zM794.624 369.626h-101.983v-101.717h101.983v101.717z" horiz-adv-x="1176" /> -<glyph unicode="" d="M132.21 661.39c-13.881 13.729-36.295 13.729-50.138 0-13.805-13.653-13.805-35.878 0-49.607l404.897-400.877c13.881-13.729 36.257-13.729 50.138 0l404.897 400.877c13.805 13.729 13.881 35.878 0 49.607s-36.371 13.729-50.138 0.038l-379.866-365.606-379.79 365.568z" /> -<glyph unicode="" d="M737.242 56.358c13.729-13.881 13.729-36.257 0-50.138s-35.878-13.881-49.607 0l-400.877 404.821c-13.729 13.881-13.729 36.295 0 50.138l400.877 404.897c13.729 13.881 35.878 13.881 49.607 0s13.729-36.257 0-50.138l-365.568-379.79 365.568-379.79z" /> -<glyph unicode="" d="M286.72 56.358c-13.729-13.881-13.729-36.257 0-50.138s35.878-13.881 49.607 0l400.877 404.821c13.729 13.881 13.729 36.295 0 50.138l-400.915 404.897c-13.729 13.881-35.878 13.881-49.607 0s-13.729-36.257 0-50.138l365.568-379.79-365.568-379.79z" /> -<glyph unicode="" d="M891.79 210.906c13.881-13.729 36.295-13.729 50.138 0 13.881 13.729 13.881 35.878 0 49.607l-404.897 400.877c-13.805 13.729-36.257 13.729-50.062 0l-404.897-400.877c-13.805-13.729-13.881-35.878 0-49.607s36.257-13.729 50.138 0l379.79 365.606 379.79-365.606z" /> -<glyph unicode="" d="M574.767 855.988c-227.593 0-412.672-182.386-418.247-409.335h-125.8l188.378-209.92 188.302 209.92h-146.242c5.537 168.998 143.777 304.393 313.609 304.393 173.397 0 313.913-140.971 313.913-314.899s-140.478-314.861-313.913-314.861c-69.48 0-133.689 22.718-185.685 61.099l-71.983-76.99c70.997-55.751 160.465-89.050 257.707-89.050 231.159 0 418.551 187.961 418.551 419.84-0.038 231.879-187.43 419.84-418.551 419.84z" /> -<glyph unicode="" d="M996.617 821.362l-513.555-513.555-256.796 256.834-128.379-128.417 385.214-385.252 641.896 642.010z" horiz-adv-x="1176" /> -<glyph unicode="" d="M512 907.188c-260.134 0-471.040-210.944-471.040-471.040 0-260.134 210.906-471.040 471.040-471.040s471.040 210.906 471.040 471.040c0 260.134-210.906 471.040-471.040 471.040zM512 67.508c-203.624 0-368.64 165.054-368.64 368.64s165.016 368.64 368.64 368.64 368.64-165.054 368.64-368.64-165.016-368.64-368.64-368.64zM547.84 702.388h-71.68v-281.069l174.345-174.345 50.669 50.707-153.335 153.335z" /> -<glyph unicode="" d="M92.312 870.476l924.331-924.369 77.672 77.71-924.293 924.331-77.71-77.672zM1094.391 870.438l-924.369-924.369-77.672 77.71 924.331 924.369 77.71-77.71z" horiz-adv-x="1176" /> -<glyph unicode="" d="M337.541-72.856h513.024l64.512 645.916h-639.128l61.592-645.916zM737.394 793.979v116.508c0 19.191-15.398 34.702-34.361 34.702h-217.847c-19.001 0-34.361-15.55-34.361-34.702v-114.574c-73.576-8.382-150.149-24.614-226.494-52.338v-106.989h738.001v109.833c0 0-90.074 31.403-224.977 47.559zM668.937 800.389c-47.749 3.224-99.252 4.096-153.297 0.986v61.44c0 9.519 7.623 17.332 17.143 17.332h118.936c9.519 0 17.218-7.813 17.218-17.332v-62.426z" horiz-adv-x="1176" /> -<glyph unicode="" d="M928.503 921.259l-111.502-112.109 156.065-156.9 111.502 112.071-156.065 156.937zM215.002 203.738l156.065-156.9 535.211 538.093-156.065 156.9-535.211-538.093zM103.917-59.013l188.985 49.873-139.302 140.098-49.683-190.009z" horiz-adv-x="1176" /> -<glyph unicode="" d="M1014.67 125.497c0 0 0 0 0 0l-310.651 310.651 310.651 310.651c0 0 0 0 0 0 3.337 3.337 5.765 7.244 7.32 11.416 4.248 11.378 1.82 24.69-7.32 33.83l-146.735 146.735c-9.14 9.14-22.452 11.567-33.83 7.32-4.172-1.555-8.078-3.982-11.416-7.32 0 0 0 0 0 0l-310.651-310.651-310.651 310.651c0 0 0 0 0 0-3.337 3.337-7.244 5.765-11.416 7.32-11.378 4.248-24.69 1.82-33.83-7.32l-146.735-146.735c-9.14-9.14-11.567-22.452-7.32-33.83 1.555-4.172 3.982-8.078 7.32-11.416 0 0 0 0 0 0l310.651-310.651-310.651-310.651c0 0 0 0 0 0-3.337-3.337-5.765-7.244-7.32-11.416-4.248-11.378-1.82-24.69 7.32-33.83l146.735-146.735c9.14-9.14 22.452-11.567 33.83-7.32 4.172 1.555 8.078 3.982 11.416 7.32 0 0 0 0 0 0l310.651 310.651 310.651-310.651c0 0 0 0 0 0 3.337-3.337 7.244-5.765 11.416-7.32 11.378-4.248 24.69-1.82 33.83 7.32l146.735 146.735c9.14 9.14 11.567 22.452 7.32 33.83-1.555 4.172-3.982 8.078-7.32 11.416z" /> -<glyph unicode="" d="M593.351 925.582c-270.336 0-489.434-219.098-489.434-489.358s219.098-489.434 489.434-489.434 489.434 219.136 489.434 489.434-219.136 489.358-489.434 489.358zM635.752 121.552c-11.985-11.719-26.396-17.636-43.16-17.636-8.154 0-15.967 1.517-23.4 4.589-7.358 3.034-13.843 7.168-19.456 12.174-5.613 5.158-10.126 11.226-13.388 18.356-3.337 7.13-4.968 14.753-4.968 22.945 0 16.308 5.992 30.303 17.977 42.060 11.947 11.681 26.396 17.598 43.198 17.598 16.308 0 30.606-5.689 42.78-16.801 12.25-11.188 18.318-24.993 18.318-41.339-0.038-16.384-5.992-30.303-17.939-41.984zM778.923 565.475c-3.982-13.767-9.747-26.396-17.18-37.774-7.471-11.454-16.498-22.49-27.079-33.071s-22.49-21.618-35.65-33.033c-11.454-9.785-20.783-18.318-27.913-25.79-7.168-7.396-12.895-14.867-17.218-22.338-4.286-7.433-7.282-15.398-9.026-24.007-1.707-8.609-2.617-49.721-2.617-62.35v-22.338h-101.376v32.616c0 13.729 0.986 56.661 3.034 67.584s5.158 21.125 9.481 30.872 10.012 19.228 17.18 28.369c7.168 9.14 16.232 18.887 27.079 29.203l38.647 36.902c10.847 9.747 20.177 20.632 27.951 32.616 7.737 12.060 11.529 26.7 11.529 43.88 0 22.3-6.978 41.036-21.011 56.206-14.071 15.17-33.944 22.793-59.695 22.793-13.16 0-25.069-2.389-35.65-7.282-10.619-4.817-19.797-11.454-27.496-19.759-7.737-8.344-13.577-17.901-17.598-28.786-3.982-10.847-6.334-21.997-6.865-33.527l-105.624 9.444c3.413 27.496 10.733 51.959 21.921 73.463 11.112 21.466 25.562 39.595 43.311 54.575 17.711 14.829 38.078 26.169 61.023 33.944 22.869 7.699 47.521 11.605 73.842 11.605 24.614 0 47.976-3.603 70.049-10.771 21.959-7.168 41.491-17.711 58.406-31.782 16.839-14.033 30.227-31.365 39.936-51.959 9.709-20.632 14.564-44.411 14.564-71.263 0-18.356-2.010-34.475-5.992-48.166z" horiz-adv-x="1176" /> -<glyph unicode="" d="M574.805 855.988c-227.631 0-412.71-182.386-418.247-409.335h-125.838l188.378-209.958 188.302 209.958h-146.242c5.537 168.998 143.777 304.393 313.647 304.393 173.359 0 313.875-140.971 313.875-314.899s-140.478-314.861-313.875-314.861c-69.518 0-133.727 22.718-185.761 61.099l-71.983-76.99c71.073-55.751 160.503-89.050 257.745-89.050 231.121 0 418.513 187.961 418.513 419.84-0.038 231.879-187.43 419.84-418.513 419.84zM537.6 661.428v-240.109l153.865-153.865 50.669 50.669-132.855 132.855v210.413h-71.68z" /> -<glyph unicode="" d="M383.462 370.638h255.693v213.043h127.795l-255.642 255.667-255.642-255.667h127.795zM852.173 370.638v-170.394h-681.754v170.394h-170.419v-340.89h1022.618v340.89z" /> -<glyph unicode="" d="M639.155 839.348h-255.693v-213.043h-127.795l255.667-255.667 255.616 255.667h-127.795zM852.173 370.638v-170.394h-681.754v170.394h-170.419v-340.89h1022.618v340.89z" /> -<glyph unicode="" d="M1021.85 437.223c0-282.176-228.749-510.925-510.925-510.925s-510.925 228.749-510.925 510.925c0 282.176 228.749 510.925 510.925 510.925s510.925-228.749 510.925-510.925z" /> -<glyph unicode="" d="M510.413 948.148c-281.907 0-510.413-228.582-510.413-510.413 0-281.933 228.506-510.464 510.413-510.464s510.387 228.557 510.387 510.464c0 281.83-228.48 510.413-510.387 510.413zM865.843 437.735c0-69.99-20.506-135.27-55.578-190.285l-490.163 490.163c55.091 35.021 120.32 55.475 190.31 55.475 195.942 0 355.43-159.411 355.43-355.354zM154.957 437.735c0 69.939 20.506 135.245 55.578 190.31l490.189-490.189c-55.066-35.072-120.371-55.501-190.31-55.501-195.942-0.026-355.456 159.437-355.456 355.379z" /> -<glyph unicode="" d="M511.77 948.148c-282.778 0-512.102-229.222-512.102-512.179 0-282.829 229.325-512.102 512.102-512.102 282.931-0.026 512.23 229.248 512.23 512.102 0 282.957-229.299 512.179-512.23 512.179zM143.718 528.18h736.205v-184.269h-736.205v184.269z" /> -</font></defs></svg> \ No newline at end of file diff --git a/lib/web/fonts/UX-Icons/UX-Icons.ttf b/lib/web/fonts/UX-Icons/UX-Icons.ttf deleted file mode 100644 index 1eba05243a164..0000000000000 Binary files a/lib/web/fonts/UX-Icons/UX-Icons.ttf and /dev/null differ diff --git a/lib/web/fonts/opensans/bold/opensans-700.eot b/lib/web/fonts/opensans/bold/opensans-700.eot deleted file mode 100644 index 5d20d916338a5..0000000000000 Binary files a/lib/web/fonts/opensans/bold/opensans-700.eot and /dev/null differ diff --git a/lib/web/fonts/opensans/bold/opensans-700.svg b/lib/web/fonts/opensans/bold/opensans-700.svg deleted file mode 100644 index 9ece857021152..0000000000000 --- a/lib/web/fonts/opensans/bold/opensans-700.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg"><defs><font horiz-adv-x="1169"><font-face units-per-em="2048" ascent="1638" descent="-410"/><glyph unicode="fi" horiz-adv-x="1417" d="M41 0zm737 889H514V0H209v889H41v147l168 82v82q0 191 94 279t301 88q158 0 281-47l-78-224q-92 29-170 29-65 0-94-38.5t-29-98.5v-70h264V889zm162 518q0 149 166 149t166-149q0-71-41.5-110.5T1106 1257q-166 0-166 150zM1258 0H953v1118h305V0z"/><glyph unicode="fl" horiz-adv-x="1417" d="M41 0zm737 889H514V0H209v889H41v147l168 82v82q0 191 94 279t301 88q158 0 281-47l-78-224q-92 29-170 29-65 0-94-38.5t-29-98.5v-70h264V889zM1258 0H953v1556h305V0z"/><glyph unicode="ffi" horiz-adv-x="2208" d="M41 0zm737 889H514V0H209v889H41v147l168 82v82q0 191 94 279t301 88q158 0 281-47l-78-224q-92 29-170 29-65 0-94-38.5t-29-98.5v-70h264V889zm793 0h-264V0h-305v889H834v147l168 82v82q0 191 94 279t301 88q158 0 281-47l-78-224q-92 29-170 29-65 0-94-38.5t-29-98.5v-70h264V889zm159 518q0 149 166 149t166-149q0-71-41.5-110.5T1896 1257q-166 0-166 150zM2048 0h-305v1118h305V0z"/><glyph unicode="ffl" horiz-adv-x="2208" d="M41 0zm737 889H514V0H209v889H41v147l168 82v82q0 191 94 279t301 88q158 0 281-47l-78-224q-92 29-170 29-65 0-94-38.5t-29-98.5v-70h264V889zm793 0h-264V0h-305v889H834v147l168 82v82q0 191 94 279t301 88q158 0 281-47l-78-224q-92 29-170 29-65 0-94-38.5t-29-98.5v-70h264V889zM2048 0h-305v1556h305V0z"/><glyph horiz-adv-x="2048"/><glyph horiz-adv-x="2048"/><glyph horiz-adv-x="1044"/><glyph horiz-adv-x="532"/><glyph horiz-adv-x="532"/><glyph horiz-adv-x="532"/><glyph unicode="!" horiz-adv-x="586" d="M416 485H172l-51 977h346zM117 143q0 84 45 127t131 43q83 0 128.5-44T467 143q0-79-46-124.5T293-27q-84 0-130 44.5T117 143z"/><glyph unicode="&quot;" horiz-adv-x="967" d="M412 1462l-41-528H174l-41 528h279zm422 0l-41-528H596l-41 528h279z"/><glyph unicode="#" horiz-adv-x="1323" d="M999 844l-47-232h258V406H913L836 0H616l78 406H500L424 0H209l74 406H45v206h277l47 232H117v209h289l77 407h219l-77-407h198l78 407h215l-78-407h240V844H999zM539 612h196l47 232H586z"/><glyph unicode="$" d="M1092 457q0-159-115-255.5T655 86v-205H518V82q-244 5-428 86v264q87-43 209.5-76T518 317v310l-67 26q-198 78-280.5 169.5T88 1049q0 145 113.5 238.5T518 1401v153h137v-149q229-10 414-92l-94-234q-156 64-320 78V862q195-75 277.5-130t121-121 38.5-154zm-301-15q0 42-34 71t-102 60V324q136 23 136 118zm-402 607q0-44 30.5-72.5T518 918v235q-129-19-129-104z"/><glyph unicode="%" horiz-adv-x="1845" d="M315 1024q0-127 22.5-189.5T410 772q96 0 96 252 0 250-96 250-50 0-72.5-61.5T315 1024zm443 2q0-230-89-345.5T408 565q-165 0-255 118.5T63 1026q0 457 345 457 169 0 259.5-118.5T758 1026zm688 436L635 0H395l811 1462h240zM1339 440q0-127 22.5-189.5T1434 188q96 0 96 252 0 250-96 250-50 0-72.5-61.5T1339 440zm443 2q0-229-89-344.5T1432-18q-165 0-255 118.5T1087 442q0 457 345 457 169 0 259.5-118.5T1782 442z"/><glyph unicode="&" horiz-adv-x="1536" d="M1536 0h-377l-115 113Q853-20 612-20 368-20 225 92T82 395q0 137 60.5 233.5T350 809q-75 86-109 164.5T207 1145q0 152 116.5 245t311.5 93q186 0 297.5-86.5T1044 1165q0-119-69-217.5T752 760l284-277q71 117 123 301h318q-36-135-99-263.5T1235 293zM403 424q0-86 64.5-137T633 236q126 0 227 61L528 627q-58-44-91.5-92T403 424zm359 709q0 53-36 83.5t-93 30.5q-67 0-105.5-32t-38.5-91q0-88 95-194 86 48 132 94.5t46 108.5z"/><glyph unicode="'" horiz-adv-x="545" d="M412 1462l-41-528H174l-41 528h279z"/><glyph unicode="(" horiz-adv-x="694" d="M82 561q0 265 77.5 496T383 1462h250q-141-193-213-424t-72-475q0-245 73.5-473.5T631-324H383Q236-154 159 73T82 561z"/><glyph unicode=")" horiz-adv-x="694" d="M612 561q0-263-77.5-490T311-324H63Q198-140 272 88.5T346 563q0 244-72 475T61 1462h250q147-175 224-406.5T612 561z"/><glyph unicode="*" horiz-adv-x="1116" d="M688 1556l-41-368 373 104 33-252-340-24 223-297-227-121-156 313-137-311-236 119 221 297-338 26 39 250 365-104-41 368h262z"/><glyph unicode="+" d="M475 612H88v219h387v390h219V831h387V612H694V227H475v385z"/><glyph unicode="," horiz-adv-x="594" d="M459 215Q407 13 283-264H63Q128 2 164 238h280z"/><glyph unicode="-" horiz-adv-x="659" d="M61 424v250h537V424H61z"/><glyph unicode="." horiz-adv-x="584" d="M117 143q0 84 45 127t131 43q83 0 128.5-44T467 143q0-79-46-124.5T293-27q-84 0-130 44.5T117 143z"/><glyph unicode="/" horiz-adv-x="846" d="M836 1462L291 0H14l545 1462h277z"/><glyph unicode="0" d="M1096 731q0-383-125.5-567T584-20q-253 0-381.5 190T74 731q0 387 125 570.5T584 1485q253 0 382.5-192T1096 731zm-715 0q0-269 46.5-385.5T584 229q108 0 156 118t48 384q0 269-48.5 386.5T584 1235q-109 0-156-117.5T381 731z"/><glyph unicode="1" d="M846 0H537v846l3 139 5 152q-77-77-107-101L270 901l-149 186 471 375h254V0z"/><glyph unicode="2" d="M1104 0H82v215l367 371q163 167 213 231.5T734 937t22 114q0 88-48.5 131T578 1225q-85 0-165-39t-167-111L78 1274q108 92 179 130t155 58.5 188 20.5q137 0 242-50t163-140 58-206q0-101-35.5-189.5T917.5 716 655 451L467 274v-14h637V0z"/><glyph unicode="3" d="M1047 1135q0-137-83-233T731 770v-6q177-22 268-107.5t91-230.5q0-211-153-328.5T500-20Q262-20 78 59v263q85-43 187-70t202-27q153 0 226 52t73 167q0 103-84 146t-268 43H303v237h113q170 0 248.5 44.5T743 1067q0 166-208 166-72 0-146.5-24T223 1126L80 1339q200 144 477 144 227 0 358.5-92t131.5-256z"/><glyph unicode="4" d="M1137 303H961V0H659v303H35v215l641 944h285V543h176V303zM659 543v248q0 62 5 180t8 137h-8q-37-82-89-160L307 543h352z"/><glyph unicode="5" d="M614 934q212 0 337.5-119T1077 489q0-245-151-377T494-20q-244 0-394 79v267q79-42 184-68.5T483 231q283 0 283 232 0 221-293 221-53 0-117-10.5T252 651l-123 66 55 745h793v-262H455l-27-287 35 7q61 14 151 14z"/><glyph unicode="6" d="M72 621q0 434 183.5 646T805 1479q125 0 196-15v-247q-89 20-176 20-159 0-259.5-48T415 1047t-59-267h13q99 170 317 170 196 0 307-123t111-340q0-234-132-370.5T606-20q-162 0-282.5 75t-186 219T72 621zm528-394q99 0 152 66.5T805 483q0 107-49.5 168.5T606 713q-94 0-160.5-61T379 510q0-119 62.5-201T600 227z"/><glyph unicode="7" d="M227 0l549 1200H55v260h1049v-194L551 0H227z"/><glyph unicode="8" d="M586 1481q210 0 338.5-95.5T1053 1128q0-112-62-199.5T791 772q164-88 235.5-183.5T1098 379q0-180-141-289.5T586-20Q346-20 209 82T72 371q0 125 66.5 222T352 764q-125 79-180 169t-55 197q0 157 130 254t339 97zM358 389q0-86 60-134t164-48q115 0 172 49.5T811 387q0 67-56.5 125.5T571 637q-213-98-213-248zm226 866q-79 0-127.5-40.5T408 1106q0-60 38.5-107.5T586 901q98 46 137 94t39 111q0 69-50 109t-128 40z"/><glyph unicode="9" d="M1098 838q0-432-182-645T365-20Q235-20 168-6v248q84-21 176-21 155 0 255 45.5t153 143T813 678h-12q-58-94-134-132t-190-38q-191 0-301 122.5T66 971q0 235 133.5 371.5T563 1479q162 0 283.5-76t186.5-220.5 65-344.5zm-529 393q-96 0-150-66t-54-190q0-106 49-168t149-62q94 0 161 61.5T791 948q0 119-62.5 201T569 1231z"/><glyph unicode=":" horiz-adv-x="584" d="M117 143q0 84 45 127t131 43q83 0 128.5-44T467 143q0-79-46-124.5T293-27q-84 0-130 44.5T117 143zm0 826q0 84 45 127t131 43q83 0 128.5-44T467 969q0-81-46.5-125.5T293 799q-84 0-130 44t-46 126z"/><glyph unicode=";" horiz-adv-x="594" d="M444 238l15-23Q407 13 283-264H63Q128 2 164 238h280zM117 969q0 84 45 127t131 43q83 0 128.5-44T467 969q0-81-46.5-125.5T293 799q-84 0-130 44t-46 126z"/><glyph unicode="<" d="M1081 203L88 641v143l993 496v-240L397 723l684-281V203z"/><glyph unicode="=" d="M88 805v219h993V805H88zm0-387v219h993V418H88z"/><glyph unicode=">" d="M88 442l684 281-684 317v240l993-496V641L88 203v239z"/><glyph unicode="?" horiz-adv-x="977" d="M276 485v74q0 96 41 167t150 151q105 75 138.5 122t33.5 105q0 65-48 99t-134 34q-150 0-342-98L6 1358q223 125 473 125 206 0 327.5-99T928 1120q0-110-50-190T688 750q-96-71-121.5-108T541 545v-60H276zm-32-342q0 84 45 127t131 43q83 0 128.5-44T594 143q0-79-46-124.5T420-27q-84 0-130 44.5T244 143z"/><glyph unicode="@" horiz-adv-x="1837" d="M1735 752q0-144-46-263.5T1559 301t-195-68q-74 0-131 35.5t-82 93.5h-16q-108-129-275-129-177 0-279 106.5T479 631q0 211 134 340t350 129q86 0 189.5-16.5T1323 1044l-23-489q0-139 76-139 64 0 102 93.5t38 244.5q0 161-67 284.5T1260.5 1227 983 1292q-202 0-351-83T403.5 969.5 324 608q0-276 147.5-423.5T899 37q106 0 233 23.5t250 68.5V-63q-214-91-475-91-380 0-592.5 200T102 602q0 247 108.5 448.5t309 316T981 1481q220 0 393-90t267-256 94-383zM711 627q0-211 172-211 90 0 137 63.5t57 206.5l13 221q-51 11-115 11-125 0-194.5-78T711 627z"/><glyph unicode="A" horiz-adv-x="1413" d="M1079 0L973 348H440L334 0H0l516 1468h379L1413 0h-334zM899 608q-147 473-165.5 535t-26.5 98q-33-128-189-633h381z"/><glyph unicode="B" horiz-adv-x="1376" d="M184 1462h455q311 0 451.5-88.5T1231 1092q0-131-61.5-215T1006 776v-10q139-31 200.5-116t61.5-226q0-200-144.5-312T731 0H184v1462zm310-579h180q126 0 182.5 39t56.5 129q0 84-61.5 120.5T657 1208H494V883zm0-246V256h202q128 0 189 49t61 150q0 182-260 182H494z"/><glyph unicode="C" horiz-adv-x="1305" d="M805 1225q-175 0-271-131.5T438 727q0-489 367-489 154 0 373 77V55Q998-20 776-20q-319 0-488 193.5T119 729q0 228 83 399.5t238.5 263T805 1483q213 0 428-103l-100-252q-82 39-165 68t-163 29z"/><glyph unicode="D" horiz-adv-x="1516" d="M1397 745q0-361-205.5-553T598 0H184v1462h459q358 0 556-189t198-528zm-322-8q0 471-416 471H494V256h133q448 0 448 481z"/><glyph unicode="E" horiz-adv-x="1147" d="M1026 0H184v1462h842v-254H494V887h495V633H494V256h532V0z"/><glyph unicode="F" horiz-adv-x="1124" d="M489 0H184v1462h838v-254H489V831h496V578H489V0z"/><glyph unicode="G" horiz-adv-x="1483" d="M739 821h580V63q-141-46-265.5-64.5T799-20q-331 0-505.5 194.5T119 733q0 354 202.5 552T883 1483q225 0 434-90l-103-248q-160 80-333 80-201 0-322-135T438 727q0-238 97.5-363.5T819 238q97 0 197 20v305H739v258z"/><glyph unicode="H" horiz-adv-x="1567" d="M1382 0h-309v631H494V0H184v1462h310V889h579v573h309V0z"/><glyph unicode="I" horiz-adv-x="678" d="M184 0v1462h310V0H184z"/><glyph unicode="J" horiz-adv-x="678" d="M31-430q-105 0-183 22v258q80-20 146-20 102 0 146 63.5T184 92v1370h310V94q0-256-117-390T31-430z"/><glyph unicode="K" horiz-adv-x="1360" d="M1360 0h-352L625 616l-131-94V0H184v1462h310V793l122 172 396 497h344L846 815z"/><glyph unicode="L" horiz-adv-x="1157" d="M184 0v1462h310V256h593V0H184z"/><glyph unicode="M" horiz-adv-x="1931" d="M803 0L451 1147h-9q19-350 19-467V0H184v1462h422L952 344h6l367 1118h422V0h-289v692q0 49 1.5 113t13.5 340h-9L1087 0H803z"/><glyph unicode="N" horiz-adv-x="1665" d="M1481 0h-394L451 1106h-9q19-293 19-418V0H184v1462h391l635-1095h7q-15 285-15 403v692h279V0z"/><glyph unicode="O" horiz-adv-x="1630" d="M1511 733q0-363-180-558T815-20 299 175 119 735t180.5 557.5T817 1485t515.5-194T1511 733zm-1067 0q0-245 93-369t278-124q371 0 371 493 0 494-369 494-185 0-279-124.5T444 733z"/><glyph unicode="P" horiz-adv-x="1286" d="M494 774h102q143 0 214 56.5T881 995q0 109-59.5 161T635 1208H494V774zm700 232q0-236-147.5-361T627 520H494V0H184v1462h467q266 0 404.5-114.5T1194 1006z"/><glyph unicode="Q" horiz-adv-x="1630" d="M1511 733q0-258-91.5-432.5T1151 45l352-393h-397L838-20h-23q-336 0-516 195T119 735t180.5 557.5T817 1485t515.5-194T1511 733zm-1067 0q0-245 93-369t278-124q371 0 371 493 0 494-369 494-185 0-279-124.5T444 733z"/><glyph unicode="R" horiz-adv-x="1352" d="M494 813h100q147 0 217 49t70 154q0 104-71.5 148T588 1208h-94V813zm0-252V0H184v1462h426q298 0 441-108.5t143-329.5q0-129-71-229.5T922 637q330-493 430-637h-344L659 561H494z"/><glyph unicode="S" horiz-adv-x="1128" d="M1047 406q0-198-142.5-312T508-20Q274-20 94 68v288q148-66 250.5-93T532 236q102 0 156.5 39T743 391q0 43-24 76.5T648.5 532 459 631q-134 63-201 121T151 887t-40 180q0 194 131.5 305T606 1483q114 0 217.5-27t216.5-76l-100-241q-117 48-193.5 67T596 1225q-88 0-135-41t-47-107q0-41 19-71.5t60.5-59T690 844q205-98 281-196.5t76-241.5z"/><glyph unicode="T" horiz-adv-x="1186" d="M748 0H438v1204H41v258h1104v-258H748V0z"/><glyph unicode="U" horiz-adv-x="1548" d="M1374 1462V516q0-162-72.5-284T1092 45 768-20q-282 0-438 144.5T174 520v942h309V567q0-169 68-248t225-79q152 0 220.5 79.5T1065 569v893h309z"/><glyph unicode="V" horiz-adv-x="1331" d="M1018 1462h313L834 0H496L0 1462h313l275-870q23-77 47.5-179.5T666 270q11 92 75 322z"/><glyph unicode="W" horiz-adv-x="1980" d="M1608 0h-353l-198 768q-11 41-37.5 169.5T989 1110q-6-54-30-173.5T922 766L725 0H373L0 1462h305l187-798q49-221 71-383 6 57 27.5 176.5T631 643l213 819h293l213-819q14-55 35-168t32-194q10 78 32 194.5t40 188.5l186 798h305z"/><glyph unicode="X" horiz-adv-x="1366" d="M1366 0h-354L672 553 332 0H0l485 754-454 708h342l315-526 309 526h334L872 737z"/><glyph unicode="Y" horiz-adv-x="1278" d="M639 860l305 602h334L793 569V0H485v559L0 1462h336z"/><glyph unicode="Z" horiz-adv-x="1186" d="M1137 0H49v201l701 1005H68v256h1050v-200L418 256h719V0z"/><glyph unicode="[" horiz-adv-x="678" d="M627-324H143v1786h484v-211H403V-113h224v-211z"/><glyph unicode="\" horiz-adv-x="846" d="M289 1462L834 0H557L12 1462h277z"/><glyph unicode="]" horiz-adv-x="678" d="M51-113h223v1364H51v211h484V-324H51v211z"/><glyph unicode="^" horiz-adv-x="1090" d="M8 520l438 950h144l495-950H846l-322 643-280-643H8z"/><glyph unicode="_" horiz-adv-x="842" d="M846-324H-4v140h850v-140z"/><glyph unicode="`" horiz-adv-x="1243" d="M707 1241q-63 44-185 142.5T332 1548v21h342q63-101 235-301v-27H707z"/><glyph unicode="a" horiz-adv-x="1237" d="M870 0l-59 152h-8Q726 55 644.5 17.5T432-20q-161 0-253.5 92T86 334q0 178 124.5 262.5T586 690l194 6v49q0 170-174 170-134 0-315-81l-101 206q193 101 428 101 225 0 345-98t120-298V0H870zm-90 518l-118-4q-133-4-198-48t-65-134q0-129 148-129 106 0 169.5 61T780 426v92z"/><glyph unicode="b" horiz-adv-x="1296" d="M782 1139q198 0 310-154.5T1204 561q0-277-115.5-429T774-20q-197 0-309 143h-21L393 0H160v1556h305v-362q0-69-12-221h12q107 166 317 166zm-98-244q-113 0-165-69.5T465 596v-33q0-180 53.5-258T688 227q94 0 149.5 86.5T893 565t-56 247.5T684 895z"/><glyph unicode="c" horiz-adv-x="1053" d="M614-20Q92-20 92 553q0 285 142 435.5T641 1139q194 0 348-76l-90-236q-72 29-134 47.5T641 893q-238 0-238-338 0-328 238-328 88 0 163 23.5T954 324V63Q880 16 804.5-2T614-20z"/><glyph unicode="d" horiz-adv-x="1296" d="M514-20q-197 0-309.5 153T92 557q0 275 114.5 428.5T522 1139q211 0 322-164h10q-23 125-23 223v358h306V0H903l-59 145h-13Q727-20 514-20zm107 243q117 0 171.5 68T852 522v33q0 180-55.5 258T616 891q-102 0-158.5-86.5T401 553t57-247.5T621 223z"/><glyph unicode="e" horiz-adv-x="1210" d="M623 922q-97 0-152-61.5T408 686h428q-2 113-59 174.5T623 922zm43-942q-270 0-422 149T92 551q0 281 140.5 434.5T621 1139q237 0 369-135t132-373V483H401q5-130 77-203t202-73q101 0 191 21t188 67V59Q979 19 888-.5T666-20z"/><glyph unicode="f" horiz-adv-x="793" d="M778 889H514V0H209v889H41v147l168 82v82q0 191 94 279t301 88q158 0 281-47l-78-224q-92 29-170 29-65 0-94-38.5t-29-98.5v-70h264V889z"/><glyph unicode="g" horiz-adv-x="1157" d="M1133 1118V963l-175-45q48-75 48-168 0-180-125.5-280.5T532 369l-55 3-45 5q-47-36-47-80 0-66 168-66h190q184 0 280.5-79T1120-80q0-196-163.5-304T487-492q-234 0-357.5 81.5T6-182Q6-81 69-13t185 97q-47 20-82 65.5T137 246q0 64 37 106.5T281 436q-88 38-139.5 122T90 756q0 183 119 283t340 100q47 0 111.5-8.5T743 1118h390zM270-158q0-63 60.5-99T500-293q164 0 257 45t93 123q0 63-55 87T625-14H467q-84 0-140.5-39.5T270-158zm111 910q0-91 41.5-144T549 555q86 0 126 53t40 144q0 202-166 202-168 0-168-202z"/><glyph unicode="h" horiz-adv-x="1346" d="M1192 0H887v653q0 242-180 242-128 0-185-87t-57-282V0H160v1556h305v-317q0-37-7-174l-7-90h16q102 164 324 164 197 0 299-106t102-304V0z"/><glyph unicode="i" horiz-adv-x="625" d="M147 1407q0 149 166 149t166-149q0-71-41.5-110.5T313 1257q-166 0-166 150zM465 0H160v1118h305V0z"/><glyph unicode="j" horiz-adv-x="625" d="M70-492q-117 0-201 25v240q70-19 143-19 77 0 112.5 43T160-76v1194h305V-121q0-178-103-274.5T70-492zm77 1899q0 149 166 149t166-149q0-71-41.5-110.5T313 1257q-166 0-166 150z"/><glyph unicode="k" horiz-adv-x="1270" d="M453 608l133 170 313 340h344L799 633 1270 0H918L596 453 465 348V0H160v1556h305V862l-16-254h4z"/><glyph unicode="l" horiz-adv-x="625" d="M465 0H160v1556h305V0z"/><glyph unicode="m" horiz-adv-x="2011" d="M1161 0H856v653q0 121-40.5 181.5T688 895q-117 0-170-86t-53-283V0H160v1118h233l41-143h17q45 77 130 120.5t195 43.5q251 0 340-164h27q45 78 132.5 121t197.5 43q190 0 287.5-97.5T1858 729V0h-306v653q0 121-40.5 181.5T1384 895q-112 0-167.5-80T1161 561V0z"/><glyph unicode="n" horiz-adv-x="1346" d="M1192 0H887v653q0 121-43 181.5T707 895q-128 0-185-85.5T465 526V0H160v1118h233l41-143h17q51 81 140.5 122.5T795 1139q195 0 296-105.5T1192 729V0z"/><glyph unicode="o" horiz-adv-x="1268" d="M403 561q0-166 54.5-251T635 225q122 0 175.5 84.5T864 561q0 166-54 249t-177 83q-122 0-176-82.5T403 561zm773 0q0-273-144-427T631-20q-161 0-284 70.5T158 253 92 561q0 274 143 426t402 152q161 0 284-70t189-201 66-307z"/><glyph unicode="p" horiz-adv-x="1296" d="M774-20q-197 0-309 143h-16q16-140 16-162v-453H160v1610h248l43-145h14q107 166 317 166 198 0 310-153t112-425q0-179-52.5-311T1002 49 774-20zm-90 915q-113 0-165-69.5T465 596v-33q0-180 53.5-258T688 227q205 0 205 338 0 165-50.5 247.5T684 895z"/><glyph unicode="q" horiz-adv-x="1296" d="M623 219q116 0 170 66.5T852 518v37q0 180-55.5 258T618 891q-215 0-215-338 0-168 53.5-251T623 219zM514-20q-198 0-310 152.5T92 557q0 274 114.5 428T520 1139q106 0 185-40t139-124h8l27 143h258V-492H831v469q0 61 13 168h-13Q782 64 701 22T514-20z"/><glyph unicode="r" horiz-adv-x="930" d="M784 1139q62 0 103-9l-23-286q-37 10-90 10-146 0-227.5-75T465 569V0H160v1118h231l45-188h15q52 94 140.5 151.5T784 1139z"/><glyph unicode="s" horiz-adv-x="1018" d="M940 332q0-172-119.5-262T463-20Q341-20 255-3.5T94 45v252q85-40 191.5-67T473 203q166 0 166 96 0 36-22 58.5t-76 51T397 475q-129 54-189.5 100t-88 105.5T92 827q0 149 115.5 230.5T535 1139q202 0 393-88l-92-220q-84 36-157 59t-149 23q-135 0-135-73 0-41 43.5-71T629 680q131-53 192-99t90-106 29-143z"/><glyph unicode="t" horiz-adv-x="889" d="M631 223q80 0 192 35V31Q709-20 543-20q-183 0-266.5 92.5T193 350v539H47v129l168 102 88 236h195v-238h313V889H498V350q0-65 36.5-96t96.5-31z"/><glyph unicode="u" horiz-adv-x="1346" d="M952 0l-41 143h-16Q846 65 756 22.5T551-20Q354-20 254 85.5T154 389v729h305V465q0-121 43-181.5T639 223q128 0 185 85.5T881 592v526h305V0H952z"/><glyph unicode="v" horiz-adv-x="1165" d="M426 0L0 1118h319l216-637q36-121 45-229h6q5 96 45 229l215 637h319L739 0H426z"/><glyph unicode="w" horiz-adv-x="1753" d="M1079 0l-86 391-116 494h-7L666 0H338L20 1118h304l129-495q31-133 63-367h6q4 76 35 241l16 85 138 536h336l131-536q4-22 12.5-65t16.5-91.5 14.5-95 7.5-74.5h6q9 72 32 197.5t33 169.5l134 495h299L1411 0h-332z"/><glyph unicode="x" horiz-adv-x="1184" d="M389 571L29 1118h346l217-356 219 356h346L793 571 1174 0H827L592 383 356 0H10z"/><glyph unicode="y" horiz-adv-x="1165" d="M0 1118h334l211-629q27-82 37-194h6q11 103 43 194l207 629h327L692-143q-65-175-185.5-262T225-492q-79 0-155 17v242q55-13 120-13 81 0 141.5 49.5T426-47l18 55z"/><glyph unicode="z" horiz-adv-x="999" d="M938 0H55v180l518 705H86v233h834V920L416 233h522V0z"/><glyph unicode="{" horiz-adv-x="807" d="M287 270q0 87-65.5 133T31 449v239q126 0 191 44t65 126v326q0 153 97 215.5t341 62.5v-225q-99-3-136.5-38T551 1096V797q-6-188-234-222v-12q234-35 234-212V43q0-68 37-103t137-38v-226q-244 0-341 62.5T287-45v315z"/><glyph unicode="|" horiz-adv-x="1128" d="M455 1550h219V-465H455v2015z"/><glyph unicode="}" horiz-adv-x="807" d="M520-45q0-112-41-169t-135.5-83.5T82-324v226q99 2 136.5 36T256 43v310q0 86 59 139.5T489 563v12q-227 34-233 222v299q0 70-37 104t-137 37v225q167 0 262-26.5t135.5-84T520 1184V856q0-84 61.5-126T776 688V449q-125 0-190.5-41T520 270V-45z"/><glyph unicode="~" d="M322 672q-55 0-117.5-33.5T88 551v231q103 109 256 109 73 0 137.5-16T621 827q129-55 227-55 53 0 116 32t117 89V662Q980 553 825 553q-66 0-126 13t-150 50q-131 56-227 56z"/><glyph unicode="¡" horiz-adv-x="586" d="M168 606h244l51-975H117zm299 342q0-84-45-127t-131-43q-83 0-128.5 44T117 948q0 81 46.5 125.5T291 1118q84 0 130-44t46-126z"/><glyph unicode="¢" d="M563 176q-420 59-420 565 0 261 104.5 403T563 1317v166h178v-158q166-9 299-74l-90-235q-72 29-134 47t-124 18q-121 0-179-83.5T455 743q0-327 237-327 82 0 148 15.5t166 60.5V238q-127-61-265-70V-20H563v196z"/><glyph unicode="£" d="M700 1483q195 0 390-82l-93-230q-157 64-272 64-78 0-120-44.5T563 1063V870h375V651H563V508q0-170-151-248h718V0H82v248q103 44 141.5 101T262 506v145H84v219h178v195q0 201 114.5 309.5T700 1483z"/><glyph unicode="¤" d="M188 723q0 102 54 197l-129 127 147 147 127-127q91 53 197 53 105 0 196-55l127 129 150-143-129-129q53-89 53-199 0-107-53-199l125-125-146-145-127 125q-95-51-196-51-115 0-199 51L260 256 115 401l127 125q-54 93-54 197zm207 0q0-77 54.5-132.5T584 535q81 0 136.5 55T776 723q0 80-56.5 135T584 913q-78 0-133.5-56T395 723z"/><glyph unicode="¥" d="M584 860l264 602h313L778 715h195V537H727V399h246V221H727V0H440v221H193v178h247v138H193v178h190L6 1462h316z"/><glyph unicode="¦" horiz-adv-x="1128" d="M455 1550h219V735H455v815zm0-1200h219v-815H455v815z"/><glyph unicode="§" horiz-adv-x="995" d="M121 805q0 79 36 144.5t97 105.5q-133 84-133 233 0 131 111.5 210t293.5 79q170 0 363-84l-82-190q-68 32-138.5 57.5T520 1386q-81 0-118-23t-37-71q0-49 49.5-86t163.5-82q163-64 240-148.5T895 782q0-177-125-260 62-40 93.5-92.5T895 303q0-148-119.5-235.5T455-20q-203 0-349 79v207q81-41 180-69.5T455 168q194 0 194 117 0 39-18.5 63T567 397.5 442 457q-183 74-252 152.5T121 805zm223 22q0-67 65-119t181-98q78 57 78 146 0 68-50.5 115T434 967q-37-14-63.5-53.5T344 827z"/><glyph unicode="¨" horiz-adv-x="1243" d="M279 1405q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T418 1272q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T823 1540q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T682 1405z"/><glyph unicode="©" horiz-adv-x="1704" d="M895 1010q-97 0-150-74t-53-205q0-280 203-280 57 0 123 15t123 44V319q-120-57-252-57-204 0-316 125T461 733q0 220 110.5 342.5T881 1198q149 0 305-78l-74-168q-113 58-217 58zM100 731q0 200 100 375t275 276 377 101q200 0 375-100t276-275 101-377q0-197-97-370T1235 84 852-20Q645-20 470 83.5T197.5 360 100 731zm142 0q0-164 82-305.5t224-223T852 121q164 0 305.5 82t223 224 81.5 304q0 164-82 305.5t-224 223-304 81.5q-164 0-305.5-82t-223-224T242 731z"/><glyph unicode="ª" horiz-adv-x="784" d="M561 764l-31 110q-43-58-105-90t-136-32q-117 0-179.5 58.5T47 975q0 109 82.5 163.5T397 1202l99 4q0 117-127 117-81 0-217-61l-66 135q66 32 145.5 57t178.5 25q137 0 211.5-71t74.5-202V764H561zM252 977q0-38 23-56t55-18q77 0 121.5 41.5T496 1051v36l-99-6q-145-10-145-104z"/><glyph unicode="«" horiz-adv-x="1260" d="M82 573l371 455 219-119-279-348 279-348L453 94 82 547v26zm506 0l370 455 220-119-279-348 279-348L958 94 588 547v26z"/><glyph unicode="¬" d="M1081 248H862v364H88v219h993V248z"/><glyph unicode="­" horiz-adv-x="659" d="M61 424zm0 0v250h537V424H61z"/><glyph unicode="®" horiz-adv-x="1704" d="M1157 905q0-170-143-233l237-400H997L819 610h-47V272H543v916h264q181 0 265.5-70t84.5-213zM772 778h31q66 0 94.5 28.5T926 901q0 65-28 92t-97 27h-29V778zm-672-47q0 200 100 375t275 276 377 101q200 0 375-100t276-275 101-377q0-197-97-370T1235 84 852-20Q645-20 470 83.5T197.5 360 100 731zm142 0q0-164 82-305.5t224-223T852 121q164 0 305.5 82t223 224 81.5 304q0 164-82 305.5t-224 223-304 81.5q-164 0-305.5-82t-223-224T242 731z"/><glyph unicode="¯" horiz-adv-x="1024" d="M1030 1556H-6v201h1036v-201z"/><glyph unicode="°" horiz-adv-x="877" d="M92 1137q0 92 46 172t126 127 174 47q92 0 172.5-46t127-127 46.5-173q0-93-46.5-173.5T611 838t-173-45q-145 0-245.5 99.5T92 1137zm191 0q0-64 44.5-109T438 983t111 46 45 108q0 63-45.5 110T438 1294q-64 0-109.5-46T283 1137z"/><glyph unicode="±" d="M475 674H88v219h387v389h219V893h387V674H694V289H475v385zM88 0v219h993V0H88z"/><glyph unicode="²" horiz-adv-x="776" d="M702 586H55v168l224 219q102 100 130.5 144.5T438 1212q0 38-24 58t-64 20q-81 0-180-88L47 1354q147 129 336 129 137 0 216-66.5t79-183.5q0-85-47-160T455 881l-105-95h352V586z"/><glyph unicode="³" horiz-adv-x="776" d="M666 1249q0-143-170-198v-13q94-20 146-75t52-134q0-121-88-190.5T332 569q-143 0-273 70v190q148-90 271-90 143 0 143 107 0 53-44 79.5T307 952H195v160h92q83 0 123.5 26t40.5 83q0 38-25 63t-76 25q-47 0-89-19t-99-59L61 1372q62 47 137.5 78t178.5 31q127 0 208-64t81-168z"/><glyph unicode="´" horiz-adv-x="1243" d="M332 1241v27q172 200 235 301h342v-21q-52-52-177.5-154.5T535 1241H332z"/><glyph unicode="µ" horiz-adv-x="1352" d="M465 465q0-121 44-181.5T647 223q126 0 183 86.5T887 592v526h305V0H961l-43 150h-15Q861 65 801 22.5T653-20q-62 0-114 23t-84 67l5-85 5-157v-320H160v1610h305V465z"/><glyph unicode="¶" horiz-adv-x="1341" d="M1167-260h-161v1616H840V-260H678v819q-62-18-146-18-216 0-317.5 125T113 1042q0 260 109 387t341 127h604V-260z"/><glyph unicode="·" horiz-adv-x="584" d="M117 723q0 84 45 127t131 43q83 0 128.5-44T467 723q0-81-46.5-125.5T293 553q-84 0-130 44t-46 126z"/><glyph unicode="¸" horiz-adv-x="420" d="M418-250q0-128-75.5-185T109-492q-78 0-146 21v168q27-7 72.5-14t70.5-7q72 0 72 62 0 83-166 108L90 0h193l-27-61q74-24 118-74.5T418-250z"/><glyph unicode="¹" horiz-adv-x="776" d="M584 586H346v446l3 112 5 95q-27-36-75-78l-78-61-109 127 301 235h191V586z"/><glyph unicode="º" horiz-adv-x="795" d="M737 1116q0-171-91.5-267.5T395 752q-153 0-245.5 98.5T57 1116q0 169 89.5 266t252.5 97q152 0 245-98.5t93-264.5zm-477 0q0-100 32.5-150.5T397 915t103.5 50.5T532 1116t-31.5 149.5T397 1315t-104.5-49.5T260 1116z"/><glyph unicode="»" horiz-adv-x="1260" d="M1178 547L807 94 588 213l278 348-278 348 219 119 371-455v-26zm-506 0L301 94 82 213l278 348L82 909l219 119 371-455v-26z"/><glyph unicode="¼" horiz-adv-x="1804" d="M46 0zm492 586H300v446l3 112 5 95q-27-36-75-78l-78-61-109 127 301 235h191V586zm832 876L559 0H320l811 1462h239zm312-1310h-125V1h-238v151H936v154l385 577h236V320h125V152zm-363 168v164q0 86 6 184-9-26-35.5-80t-41.5-77l-127-191h198z"/><glyph unicode="½" horiz-adv-x="1804" d="M46 0zm492 586H300v446l3 112 5 95q-27-36-75-78l-78-61-109 127 301 235h191V586zm832 876L559 0H320l811 1462h239zM1716 1h-647v168l224 219q102 100 130.5 144.5T1452 627q0 38-24 58t-64 20q-81 0-180-88l-123 152q147 129 336 129 137 0 216-66.5t79-183.5q0-85-47-160t-176-192l-105-95h352V1z"/><glyph unicode="¾" horiz-adv-x="1804" d="M90 0zm607 1249q0-143-170-198v-13q94-20 146-75t52-134q0-121-88-190.5T363 569q-143 0-273 70v190q148-90 271-90 143 0 143 107 0 53-44 79.5T338 952H226v160h92q83 0 123.5 26t40.5 83q0 38-25 63t-76 25q-47 0-89-19t-99-59L92 1372q62 47 137.5 78t178.5 31q127 0 208-64t81-168zm744 213L630 0H391l811 1462h239zm271-1310h-125V1h-238v151H966v154l385 577h236V320h125V152zm-363 168v164q0 86 6 184-9-26-35.5-80t-41.5-77l-127-191h198z"/><glyph unicode="¿" horiz-adv-x="977" d="M713 606v-74q0-98-44.5-169T516 215Q407 137 378.5 93T350-14q0-57 43.5-94T526-145q79 0 169 29t186 71l102-221q-98-56-221.5-90.5T532-391q-220 0-345.5 96.5T61-29q0 108 48.5 187T301 342q95 70 121.5 107t26.5 98v59h264zm32 342q0-84-45-127t-131-43q-83 0-128.5 44T395 948q0 81 46.5 125.5T569 1118q84 0 130-44t46-126z"/><glyph unicode="À" horiz-adv-x="1413" d="M0 0zm1079 0L973 348H440L334 0H0l516 1468h379L1413 0h-334zM899 608q-147 473-165.5 535t-26.5 98q-33-128-189-633h381zm-186 971q-63 44-185 142.5T338 1886v21h342q63-101 235-301v-27H713z"/><glyph unicode="Á" horiz-adv-x="1413" d="M0 0zm1079 0L973 348H440L334 0H0l516 1468h379L1413 0h-334zM899 608q-147 473-165.5 535t-26.5 98q-33-128-189-633h381zm-358 971v27q172 200 235 301h342v-21q-52-52-177.5-154.5T744 1579H541z"/><glyph unicode="Â" horiz-adv-x="1413" d="M0 0zm1079 0L973 348H440L334 0H0l516 1468h379L1413 0h-334zM899 608q-147 473-165.5 535t-26.5 98q-33-128-189-633h381zm39 971q-157 93-234 176-78-81-229-176H272v27q189 189 256 301h357q31-52 107.5-141.5T1141 1606v-27H938z"/><glyph unicode="Ã" horiz-adv-x="1413" d="M0 0zm1079 0L973 348H440L334 0H0l516 1468h379L1413 0h-334zM899 608q-147 473-165.5 535t-26.5 98q-33-128-189-633h381zM543 1684q-31 0-59.5-26.5T442 1577H293q11 145 82.5 227t189.5 82q41 0 80.5-16.5t78-36T799 1798t73-16q31 0 59.5 26t41.5 80h149q-11-145-83.5-227T850 1579q-41 0-80.5 16.5t-78 36-75.5 36-73 16.5z"/><glyph unicode="Ä" horiz-adv-x="1413" d="M0 0zm1079 0L973 348H440L334 0H0l516 1468h379L1413 0h-334zM899 608q-147 473-165.5 535t-26.5 98q-33-128-189-633h381zM365 1743q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T504 1610q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T909 1878q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T768 1743z"/><glyph unicode="Å" horiz-adv-x="1413" d="M0 0zm1079 0L973 348H440L334 0H0l516 1468h379L1413 0h-334zM899 608q-147 473-165.5 535t-26.5 98q-33-128-189-633h381zm60 959q0-108-71-174t-183-66-180 64-68 174q0 108 67.5 172.5T705 1802q110 0 182-66t72-169zm-158-2q0 45-27 70.5t-69 25.5-69-25.5-27-70.5 24-71 72-26q42 0 69 26t27 71z"/><glyph unicode="Æ" horiz-adv-x="1950" d="M1829 0H956v348H465L315 0H0l655 1462h1174v-254h-563V887h526V633h-526V256h563V0zM578 608h378v590H829z"/><glyph unicode="Ç" horiz-adv-x="1305" d="M119 0zm686 1225q-175 0-271-131.5T438 727q0-489 367-489 154 0 373 77V55Q998-20 776-20q-319 0-488 193.5T119 729q0 228 83 399.5t238.5 263T805 1483q213 0 428-103l-100-252q-82 39-165 68t-163 29zM959-250q0-128-75.5-185T650-492q-78 0-146 21v168q27-7 72.5-14t70.5-7q72 0 72 62 0 83-166 108L631 0h193l-27-61q74-24 118-74.5T959-250z"/><glyph unicode="È" horiz-adv-x="1147" d="M184 0zm842 0H184v1462h842v-254H494V887h495V633H494V256h532V0zM634 1579q-63 44-185 142.5T259 1886v21h342q63-101 235-301v-27H634z"/><glyph unicode="É" horiz-adv-x="1147" d="M184 0zm842 0H184v1462h842v-254H494V887h495V633H494V256h532V0zM424 1579v27q172 200 235 301h342v-21q-52-52-177.5-154.5T627 1579H424z"/><glyph unicode="Ê" horiz-adv-x="1147" d="M175 0zm851 0H184v1462h842v-254H494V887h495V633H494V256h532V0zM841 1579q-157 93-234 176-78-81-229-176H175v27q189 189 256 301h357q31-52 107.5-141.5T1044 1606v-27H841z"/><glyph unicode="Ë" horiz-adv-x="1147" d="M184 0zm842 0H184v1462h842v-254H494V887h495V633H494V256h532V0zM272 1743q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T411 1610q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T816 1878q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T675 1743z"/><glyph unicode="Ì" horiz-adv-x="678" d="M0 0zm184 0v1462h310V0H184zm133 1579q-63 44-185 142.5T-58 1886v21h342q63-101 235-301v-27H317z"/><glyph unicode="Í" horiz-adv-x="678" d="M167 0zm17 0v1462h310V0H184zm-17 1579v27q172 200 235 301h342v-21q-52-52-177.5-154.5T370 1579H167z"/><glyph unicode="Î" horiz-adv-x="678" d="M0 0zm184 0v1462h310V0H184zm386 1579q-157 93-234 176-78-81-229-176H-96v27q189 189 256 301h357q31-52 107.5-141.5T773 1606v-27H570z"/><glyph unicode="Ï" horiz-adv-x="678" d="M0 0zm184 0v1462h310V0H184zM-3 1743q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T136 1610q-64 0-101.5 35T-3 1743zm403 0q0 70 40.5 102.5T541 1878q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T400 1743z"/><glyph unicode="Ð" horiz-adv-x="1516" d="M47 850h137v612h459q358 0 556-189t198-528q0-361-205.5-553T598 0H184v596H47v254zm1028-113q0 232-104 351.5T657 1208H494V850h237V596H494V256h131q450 0 450 481z"/><glyph unicode="Ñ" horiz-adv-x="1665" d="M184 0zm1297 0h-394L451 1106h-9q19-293 19-418V0H184v1462h391l635-1095h7q-15 285-15 403v692h279V0zM668 1684q-31 0-59.5-26.5T567 1577H418q11 145 82.5 227t189.5 82q41 0 80.5-16.5t78-36T924 1798t73-16q31 0 59.5 26t41.5 80h149q-11-145-83.5-227T975 1579q-41 0-80.5 16.5t-78 36-75.5 36-73 16.5z"/><glyph unicode="Ò" horiz-adv-x="1630" d="M119 0zm1392 733q0-363-180-558T815-20 299 175 119 735t180.5 557.5T817 1485t515.5-194T1511 733zm-1067 0q0-245 93-369t278-124q371 0 371 493 0 494-369 494-185 0-279-124.5T444 733zm380 846q-63 44-185 142.5T449 1886v21h342q63-101 235-301v-27H824z"/><glyph unicode="Ó" horiz-adv-x="1630" d="M119 0zm1392 733q0-363-180-558T815-20 299 175 119 735t180.5 557.5T817 1485t515.5-194T1511 733zm-1067 0q0-245 93-369t278-124q371 0 371 493 0 494-369 494-185 0-279-124.5T444 733zm214 846v27q172 200 235 301h342v-21q-52-52-177.5-154.5T861 1579H658z"/><glyph unicode="Ô" horiz-adv-x="1630" d="M119 0zm1392 733q0-363-180-558T815-20 299 175 119 735t180.5 557.5T817 1485t515.5-194T1511 733zm-1067 0q0-245 93-369t278-124q371 0 371 493 0 494-369 494-185 0-279-124.5T444 733zm603 846q-157 93-234 176-78-81-229-176H381v27q189 189 256 301h357q31-52 107.5-141.5T1250 1606v-27h-203z"/><glyph unicode="Õ" horiz-adv-x="1630" d="M119 0zm1392 733q0-363-180-558T815-20 299 175 119 735t180.5 557.5T817 1485t515.5-194T1511 733zm-1067 0q0-245 93-369t278-124q371 0 371 493 0 494-369 494-185 0-279-124.5T444 733zm208 951q-31 0-59.5-26.5T551 1577H402q11 145 82.5 227t189.5 82q41 0 80.5-16.5t78-36T908 1798t73-16q31 0 59.5 26t41.5 80h149q-11-145-83.5-227T959 1579q-41 0-80.5 16.5t-78 36-75.5 36-73 16.5z"/><glyph unicode="Ö" horiz-adv-x="1630" d="M119 0zm1392 733q0-363-180-558T815-20 299 175 119 735t180.5 557.5T817 1485t515.5-194T1511 733zm-1067 0q0-245 93-369t278-124q371 0 371 493 0 494-369 494-185 0-279-124.5T444 733zm30 1010q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T613 1610q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T1018 1878q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T877 1743z"/><glyph unicode="×" d="M428 723l-299 301 152 154 301-299 305 299 153-150-305-305 301-303-149-152-305 301-301-299-150 152z"/><glyph unicode="Ø" horiz-adv-x="1630" d="M1511 733q0-363-180-558T815-20q-197 0-336 65L389-90 227 18l90 136Q119 348 119 735q0 365 180.5 557.5T817 1485q198 0 344-70l84 125 160-104-88-131q194-194 194-572zm-1067 0q0-191 56-307l506 756q-84 45-189 45-185 0-279-124.5T444 733zm742 0q0 180-51 297L635 279q76-39 180-39 371 0 371 493z"/><glyph unicode="Ù" horiz-adv-x="1548" d="M174 0zm1200 1462V516q0-162-72.5-284T1092 45 768-20q-282 0-438 144.5T174 520v942h309V567q0-169 68-248t225-79q152 0 220.5 79.5T1065 569v893h309zm-624 117q-63 44-185 142.5T375 1886v21h342q63-101 235-301v-27H750z"/><glyph unicode="Ú" horiz-adv-x="1548" d="M174 0zm1200 1462V516q0-162-72.5-284T1092 45 768-20q-282 0-438 144.5T174 520v942h309V567q0-169 68-248t225-79q152 0 220.5 79.5T1065 569v893h309zm-772 117v27q172 200 235 301h342v-21q-52-52-177.5-154.5T805 1579H602z"/><glyph unicode="Û" horiz-adv-x="1548" d="M174 0zm1200 1462V516q0-162-72.5-284T1092 45 768-20q-282 0-438 144.5T174 520v942h309V567q0-169 68-248t225-79q152 0 220.5 79.5T1065 569v893h309zm-368 117q-157 93-234 176-78-81-229-176H340v27q189 189 256 301h357q31-52 107.5-141.5T1209 1606v-27h-203z"/><glyph unicode="Ü" horiz-adv-x="1548" d="M174 0zm1200 1462V516q0-162-72.5-284T1092 45 768-20q-282 0-438 144.5T174 520v942h309V567q0-169 68-248t225-79q152 0 220.5 79.5T1065 569v893h309zm-941 281q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T572 1610q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T977 1878q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T836 1743z"/><glyph unicode="Ý" horiz-adv-x="1278" d="M0 0zm639 860l305 602h334L793 569V0H485v559L0 1462h336zm-178 719v27q172 200 235 301h342v-21q-52-52-177.5-154.5T664 1579H461z"/><glyph unicode="Þ" horiz-adv-x="1286" d="M1194 770q0-229-142.5-353T647 293H494V0H184v1462h310v-229h178q254 0 388-119t134-344zM494 543h100q145 0 216 52.5T881 770q0 107-63.5 159T618 981H494V543z"/><glyph unicode="ß" horiz-adv-x="1456" d="M1249 1241q0-64-21-112.5t-53-86.5-69-67-69-53-53-45-21-43q0-27 26.5-53t92.5-66q146-91 198.5-140t78-110 25.5-139q0-172-116.5-259T924-20q-99 0-171 14.5T621 43v242q53-36 135.5-61T903 199q168 0 168 123 0 41-16 66.5T998 444t-115 72q-126 72-175 131.5T659 788q0 64 35 117t105 102q77 55 108 95t31 86q0 60-63.5 100.5T711 1329q-116 0-181-52.5T465 1128V0H160v1139q0 201 146.5 314.5T711 1567q244 0 391-88.5t147-237.5z"/><glyph unicode="à" horiz-adv-x="1237" d="M86 0zm784 0l-59 152h-8Q726 55 644.5 17.5T432-20q-161 0-253.5 92T86 334q0 178 124.5 262.5T586 690l194 6v49q0 170-174 170-134 0-315-81l-101 206q193 101 428 101 225 0 345-98t120-298V0H870zm-90 518l-118-4q-133-4-198-48t-65-134q0-129 148-129 106 0 169.5 61T780 426v92zm-166 723q-63 44-185 142.5T239 1548v21h342q63-101 235-301v-27H614z"/><glyph unicode="á" horiz-adv-x="1237" d="M86 0zm784 0l-59 152h-8Q726 55 644.5 17.5T432-20q-161 0-253.5 92T86 334q0 178 124.5 262.5T586 690l194 6v49q0 170-174 170-134 0-315-81l-101 206q193 101 428 101 225 0 345-98t120-298V0H870zm-90 518l-118-4q-133-4-198-48t-65-134q0-129 148-129 106 0 169.5 61T780 426v92zm-339 723v27q172 200 235 301h342v-21q-52-52-177.5-154.5T644 1241H441z"/><glyph unicode="â" horiz-adv-x="1237" d="M86 0zm784 0l-59 152h-8Q726 55 644.5 17.5T432-20q-161 0-253.5 92T86 334q0 178 124.5 262.5T586 690l194 6v49q0 170-174 170-134 0-315-81l-101 206q193 101 428 101 225 0 345-98t120-298V0H870zm-90 518l-118-4q-133-4-198-48t-65-134q0-129 148-129 106 0 169.5 61T780 426v92zm63 722q-157 93-234 176-78-81-229-176H177v27q189 189 256 301h357q31-52 107.5-141.5T1046 1267v-27H843z"/><glyph unicode="ã" horiz-adv-x="1237" d="M86 0zm784 0l-59 152h-8Q726 55 644.5 17.5T432-20q-161 0-253.5 92T86 334q0 178 124.5 262.5T586 690l194 6v49q0 170-174 170-134 0-315-81l-101 206q193 101 428 101 225 0 345-98t120-298V0H870zm-90 518l-118-4q-133-4-198-48t-65-134q0-129 148-129 106 0 169.5 61T780 426v92zm-313 828q-31 0-59.5-26.5T366 1239H217q11 145 82.5 227t189.5 82q41 0 80.5-16.5t78-36T723 1460t73-16q31 0 59.5 26t41.5 80h149q-11-145-83.5-227T774 1241q-41 0-80.5 16.5t-78 36-75.5 36-73 16.5z"/><glyph unicode="ä" horiz-adv-x="1237" d="M86 0zm784 0l-59 152h-8Q726 55 644.5 17.5T432-20q-161 0-253.5 92T86 334q0 178 124.5 262.5T586 690l194 6v49q0 170-174 170-134 0-315-81l-101 206q193 101 428 101 225 0 345-98t120-298V0H870zm-90 518l-118-4q-133-4-198-48t-65-134q0-129 148-129 106 0 169.5 61T780 426v92zm-495 887q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T424 1272q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T829 1540q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T688 1405z"/><glyph unicode="å" horiz-adv-x="1237" d="M86 0zm784 0l-59 152h-8Q726 55 644.5 17.5T432-20q-161 0-253.5 92T86 334q0 178 124.5 262.5T586 690l194 6v49q0 170-174 170-134 0-315-81l-101 206q193 101 428 101 225 0 345-98t120-298V0H870zm-90 518l-118-4q-133-4-198-48t-65-134q0-129 148-129 106 0 169.5 61T780 426v92zm103 961q0-108-71-174t-183-66-180 64-68 174q0 108 67.5 172.5T629 1714q110 0 182-66t72-169zm-158-2q0 45-27 70.5t-69 25.5-69-25.5-27-70.5 24-71 72-26q42 0 69 26t27 71z"/><glyph unicode="æ" horiz-adv-x="1878" d="M1329-20q-137 0-249.5 50.5T895 186Q797 69 698.5 24.5T442-20q-161 0-258.5 94.5T86 334q0 178 121 262.5T569 690l191 6v84q0 69-44.5 102T594 915q-140 0-305-77l-99 202q189 101 422 101 227 0 342-131 66 64 152.5 96.5T1313 1139q221 0 349-137.5T1790 631V483h-723q5-130 77-203t202-73q196 0 380 88V59q-79-39-171-59t-226-20zM760 518l-113-4q-124-4-186-47.5T399 332q0-129 140-129 101 0 161 61t60 162v92zm547 404q-217 0-234-236h430q-2 112-55 174t-141 62z"/><glyph unicode="ç" horiz-adv-x="1053" d="M92 0zm522-20Q92-20 92 553q0 285 142 435.5T641 1139q194 0 348-76l-90-236q-72 29-134 47.5T641 893q-238 0-238-338 0-328 238-328 88 0 163 23.5T954 324V63Q880 16 804.5-2T614-20zm191-230q0-128-75.5-185T496-492q-78 0-146 21v168q27-7 72.5-14t70.5-7q72 0 72 62 0 83-166 108L477 0h193l-27-61q74-24 118-74.5T805-250z"/><glyph unicode="è" horiz-adv-x="1210" d="M92 0zm531 922q-97 0-152-61.5T408 686h428q-2 113-59 174.5T623 922zm43-942q-270 0-422 149T92 551q0 281 140.5 434.5T621 1139q237 0 369-135t132-373V483H401q5-130 77-203t202-73q101 0 191 21t188 67V59Q979 19 888-.5T666-20zm-46 1261q-63 44-185 142.5T245 1548v21h342q63-101 235-301v-27H620z"/><glyph unicode="é" horiz-adv-x="1210" d="M92 0zm531 922q-97 0-152-61.5T408 686h428q-2 113-59 174.5T623 922zm43-942q-270 0-422 149T92 551q0 281 140.5 434.5T621 1139q237 0 369-135t132-373V483H401q5-130 77-203t202-73q101 0 191 21t188 67V59Q979 19 888-.5T666-20zM447 1241v27q172 200 235 301h342v-21q-52-52-177.5-154.5T650 1241H447z"/><glyph unicode="ê" horiz-adv-x="1210" d="M92 0zm531 922q-97 0-152-61.5T408 686h428q-2 113-59 174.5T623 922zm43-942q-270 0-422 149T92 551q0 281 140.5 434.5T621 1139q237 0 369-135t132-373V483H401q5-130 77-203t202-73q101 0 191 21t188 67V59Q979 19 888-.5T666-20zm194 1261q-157 93-234 176-78-81-229-176H194v27q189 189 256 301h357q31-52 107.5-141.5T1063 1268v-27H860z"/><glyph unicode="ë" horiz-adv-x="1210" d="M92 0zm531 922q-97 0-152-61.5T408 686h428q-2 113-59 174.5T623 922zm43-942q-270 0-422 149T92 551q0 281 140.5 434.5T621 1139q237 0 369-135t132-373V483H401q5-130 77-203t202-73q101 0 191 21t188 67V59Q979 19 888-.5T666-20zM297 1405q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T436 1272q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T841 1540q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T700 1405z"/><glyph unicode="ì" horiz-adv-x="625" d="M0 0zm465 0H160v1118h305V0zM274 1241q-63 44-185 142.5T-101 1548v21h342q63-101 235-301v-27H274z"/><glyph unicode="í" horiz-adv-x="625" d="M145 0zm320 0H160v1118h305V0zM145 1241v27q172 200 235 301h342v-21q-52-52-177.5-154.5T348 1241H145z"/><glyph unicode="î" horiz-adv-x="625" d="M0 0zm465 0H160v1118h305V0zm79 1241q-157 93-234 176-78-81-229-176h-203v27q189 189 256 301h357q31-52 107.5-141.5T747 1268v-27H544z"/><glyph unicode="ï" horiz-adv-x="625" d="M0 0zm465 0H160v1118h305V0zM-29 1405q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T110 1272q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T515 1540q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T374 1405z"/><glyph unicode="ð" horiz-adv-x="1268" d="M510 1303q-80 53-152 92l101 176q144-65 258-141l225 139 100-154-170-104q156-143 230-324.5t74-413.5q0-280-145-436.5T631-20q-245 0-392 137T92 489q0 233 130 369.5T573 995q205 0 275-98l8 4q-67 162-192 281l-230-142-100 156zm354-771q0 108-61 173t-168 65q-121 0-176.5-68.5T403 487q0-140 60-211t172-71q123 0 176 82t53 245z"/><glyph unicode="ñ" horiz-adv-x="1346" d="M160 0zm1032 0H887v653q0 121-43 181.5T707 895q-128 0-185-85.5T465 526V0H160v1118h233l41-143h17q51 81 140.5 122.5T795 1139q195 0 296-105.5T1192 729V0zM508 1346q-31 0-59.5-26.5T407 1239H258q11 145 82.5 227t189.5 82q41 0 80.5-16.5t78-36T764 1460t73-16q31 0 59.5 26t41.5 80h149q-11-145-83.5-227T815 1241q-41 0-80.5 16.5t-78 36-75.5 36-73 16.5z"/><glyph unicode="ò" horiz-adv-x="1268" d="M92 0zm311 561q0-166 54.5-251T635 225q122 0 175.5 84.5T864 561q0 166-54 249t-177 83q-122 0-176-82.5T403 561zm773 0q0-273-144-427T631-20q-161 0-284 70.5T158 253 92 561q0 274 143 426t402 152q161 0 284-70t189-201 66-307zm-564 680q-63 44-185 142.5T237 1548v21h342q63-101 235-301v-27H612z"/><glyph unicode="ó" horiz-adv-x="1268" d="M92 0zm311 561q0-166 54.5-251T635 225q122 0 175.5 84.5T864 561q0 166-54 249t-177 83q-122 0-176-82.5T403 561zm773 0q0-273-144-427T631-20q-161 0-284 70.5T158 253 92 561q0 274 143 426t402 152q161 0 284-70t189-201 66-307zm-709 680v27q172 200 235 301h342v-21q-52-52-177.5-154.5T670 1241H467z"/><glyph unicode="ô" horiz-adv-x="1268" d="M92 0zm311 561q0-166 54.5-251T635 225q122 0 175.5 84.5T864 561q0 166-54 249t-177 83q-122 0-176-82.5T403 561zm773 0q0-273-144-427T631-20q-161 0-284 70.5T158 253 92 561q0 274 143 426t402 152q161 0 284-70t189-201 66-307zm-312 680q-157 93-234 176-78-81-229-176H198v27q189 189 256 301h357q31-52 107.5-141.5T1067 1268v-27H864z"/><glyph unicode="õ" horiz-adv-x="1268" d="M92 0zm311 561q0-166 54.5-251T635 225q122 0 175.5 84.5T864 561q0 166-54 249t-177 83q-122 0-176-82.5T403 561zm773 0q0-273-144-427T631-20q-161 0-284 70.5T158 253 92 561q0 274 143 426t402 152q161 0 284-70t189-201 66-307zm-707 785q-31 0-59.5-26.5T368 1239H219q11 145 82.5 227t189.5 82q41 0 80.5-16.5t78-36T725 1460t73-16q31 0 59.5 26t41.5 80h149q-11-145-83.5-227T776 1241q-41 0-80.5 16.5t-78 36-75.5 36-73 16.5z"/><glyph unicode="ö" horiz-adv-x="1268" d="M92 0zm311 561q0-166 54.5-251T635 225q122 0 175.5 84.5T864 561q0 166-54 249t-177 83q-122 0-176-82.5T403 561zm773 0q0-273-144-427T631-20q-161 0-284 70.5T158 253 92 561q0 274 143 426t402 152q161 0 284-70t189-201 66-307zm-885 844q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T430 1272q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T835 1540q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T694 1405z"/><glyph unicode="÷" d="M88 612v219h993V612H88zm356-239q0 76 37 113.5T584 524t102.5-39T723 373q0-70-37-111t-102-41-102.5 39T444 373zm0 698q0 75 37 113.5t103 38.5q67 0 103-40.5t36-111.5q0-70-37-110.5T584 920t-102.5 39-37.5 112z"/><glyph unicode="ø" horiz-adv-x="1268" d="M1176 561q0-273-144-427T631-20q-126 0-234 45L330-76 176 29l68 100Q92 285 92 561q0 274 143 426t402 152q132 0 248-52l55 82 152-108-58-84q142-155 142-416zm-773 0q0-94 19-166l317 475q-43 23-106 23-122 0-176-82.5T403 561zm461 0q0 81-12 141L543 240q38-15 92-15 122 0 175.5 84.5T864 561z"/><glyph unicode="ù" horiz-adv-x="1346" d="M154 0zm798 0l-41 143h-16Q846 65 756 22.5T551-20Q354-20 254 85.5T154 389v729h305V465q0-121 43-181.5T639 223q128 0 185 85.5T881 592v526h305V0H952zM620 1241q-63 44-185 142.5T245 1548v21h342q63-101 235-301v-27H620z"/><glyph unicode="ú" horiz-adv-x="1346" d="M154 0zm798 0l-41 143h-16Q846 65 756 22.5T551-20Q354-20 254 85.5T154 389v729h305V465q0-121 43-181.5T639 223q128 0 185 85.5T881 592v526h305V0H952zM498 1241v27q172 200 235 301h342v-21q-52-52-177.5-154.5T701 1241H498z"/><glyph unicode="û" horiz-adv-x="1346" d="M154 0zm798 0l-41 143h-16Q846 65 756 22.5T551-20Q354-20 254 85.5T154 389v729h305V465q0-121 43-181.5T639 223q128 0 185 85.5T881 592v526h305V0H952zm-51 1241q-157 93-234 176-78-81-229-176H235v27q189 189 256 301h357q31-52 107.5-141.5T1104 1268v-27H901z"/><glyph unicode="ü" horiz-adv-x="1346" d="M154 0zm798 0l-41 143h-16Q846 65 756 22.5T551-20Q354-20 254 85.5T154 389v729h305V465q0-121 43-181.5T639 223q128 0 185 85.5T881 592v526h305V0H952zM326 1405q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T465 1272q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T870 1540q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T729 1405z"/><glyph unicode="ý" horiz-adv-x="1165" d="M0 0zm0 1118h334l211-629q27-82 37-194h6q11 103 43 194l207 629h327L692-143q-65-175-185.5-262T225-492q-79 0-155 17v242q55-13 120-13 81 0 141.5 49.5T426-47l18 55zm393 123v27q172 200 235 301h342v-21q-52-52-177.5-154.5T596 1241H393z"/><glyph unicode="þ" horiz-adv-x="1296" d="M465 973q50 81 131 123.5t186 42.5q198 0 310-154.5T1204 561q0-273-111.5-427T782-20q-213 0-317 137h-14l7-62 7-94v-453H160v2048h305v-391l-7-120-7-72h14zm219-78q-113 0-165-69.5T465 596v-33q0-180 53.5-258T688 227q205 0 205 338 0 165-50.5 247.5T684 895z"/><glyph unicode="ÿ" horiz-adv-x="1165" d="M0 0zm0 1118h334l211-629q27-82 37-194h6q11 103 43 194l207 629h327L692-143q-65-175-185.5-262T225-492q-79 0-155 17v242q55-13 120-13 81 0 141.5 49.5T426-47l18 55zm243 287q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T382 1272q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T787 1540q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T646 1405z"/><glyph unicode="ı" horiz-adv-x="625" d="M465 0H160v1118h305V0z"/><glyph unicode="Œ" horiz-adv-x="1993" d="M1872 0H999q-38-9-109-14.5T774-20q-319 0-487 197T119 735q0 363 169.5 556.5T776 1485q61 0 127-7t101-16h868v-254h-563V887h526V633h-526V256h563V0zM776 1227q-166 0-252-125.5T438 733q0-244 86-368.5T774 240q65 0 126 10.5t99 28.5v907q-35 19-101.5 30T776 1227z"/><glyph unicode="œ" horiz-adv-x="2003" d="M1446-20q-271 0-420 155Q885-20 635-20q-162 0-286 70T158.5 252 92 561q0 277 141.5 427.5T633 1139q112 0 212-39.5T1016 983q144 156 383 156 244 0 380-135t136-373V483h-746v-8q7-127 81.5-197.5T1458 207q107 0 200 21t193 67V59q-81-39-175.5-59T1446-20zM403 561q0-166 54.5-251T635 225q122 0 175.5 84.5T864 561q0 166-54 249t-177 83q-122 0-176-82.5T403 561zm1002 361q-94 0-156-57.5T1178 686h450q-2 111-60.5 173.5T1405 922z"/><glyph unicode="Ÿ" horiz-adv-x="1278" d="M0 0zm639 860l305 602h334L793 569V0H485v559L0 1462h336zm-342 883q0 65 37.5 100t101.5 35q66 0 103.5-37t37.5-98q0-60-38-96.5T436 1610q-64 0-101.5 35t-37.5 98zm403 0q0 70 40.5 102.5T841 1878q65 0 103.5-36t38.5-99q0-61-39-97t-103-36q-60 0-100.5 32.5T700 1743z"/><glyph unicode="ˆ" horiz-adv-x="1243" d="M852 1241q-157 93-234 176-78-81-229-176H186v27q189 189 256 301h357q31-52 107.5-141.5T1055 1268v-27H852z"/><glyph unicode="˚" horiz-adv-x="1182" d="M842 1479q0-108-71-174t-183-66-180 64-68 174q0 108 67.5 172.5T588 1714q110 0 182-66t72-169zm-158-2q0 45-27 70.5t-69 25.5-69-25.5-27-70.5 24-71 72-26q42 0 69 26t27 71z"/><glyph unicode="˜" horiz-adv-x="1243" d="M457 1346q-31 0-59.5-26.5T356 1239H207q11 145 82.5 227t189.5 82q41 0 80.5-16.5t78-36T713 1460t73-16q31 0 59.5 26t41.5 80h149q-11-145-83.5-227T764 1241q-41 0-80.5 16.5t-78 36-75.5 36-73 16.5z"/><glyph horiz-adv-x="953"/><glyph horiz-adv-x="1907"/><glyph horiz-adv-x="953"/><glyph horiz-adv-x="1907"/><glyph horiz-adv-x="635"/><glyph horiz-adv-x="476"/><glyph horiz-adv-x="317"/><glyph horiz-adv-x="317"/><glyph horiz-adv-x="238"/><glyph horiz-adv-x="381"/><glyph horiz-adv-x="105"/><glyph unicode="‐" horiz-adv-x="659" d="M61 424v250h537V424H61z"/><glyph unicode="‑" horiz-adv-x="659" d="M61 424v250h537V424H61z"/><glyph unicode="‒" horiz-adv-x="659" d="M61 424v250h537V424H61z"/><glyph unicode="–" horiz-adv-x="1024" d="M82 436v230h860V436H82z"/><glyph unicode="—" horiz-adv-x="2048" d="M82 436v230h1884V436H82z"/><glyph unicode="‘" horiz-adv-x="444" d="M39 961l-14 22q22 91 72.5 228.5T201 1462h219q-66-267-101-501H39z"/><glyph unicode="’" horiz-adv-x="444" d="M406 1462l14-22q-50-197-176-479H25q69 296 100 501h281z"/><glyph unicode="‚" horiz-adv-x="596" d="M459 215Q407 13 283-264H63Q128 2 164 238h280z"/><glyph unicode="“" horiz-adv-x="911" d="M492 983q22 91 72.5 228.5T668 1462h219q-66-267-101-501H506zm-467 0q22 91 72.5 228.5T201 1462h219q-66-267-101-501H39z"/><glyph unicode="”" horiz-adv-x="911" d="M420 1440q-50-197-176-479H25q69 296 100 501h281zm467 0q-50-197-176-479H492q69 296 100 501h280z"/><glyph unicode="„" horiz-adv-x="1061" d="M459 215Q407 13 283-264H63Q128 2 164 238h280zm467 0Q874 13 750-264H530Q595 2 631 238h280z"/><glyph unicode="•" horiz-adv-x="770" d="M98 748q0 154 74 235.5t213 81.5q137 0 212-82t75-235q0-152-75.5-235T385 430q-138 0-212.5 83T98 748z"/><glyph unicode="…" horiz-adv-x="1751" d="M117 143q0 84 45 127t131 43q83 0 128.5-44T467 143q0-79-46-124.5T293-27q-84 0-130 44.5T117 143zm583 0q0 84 45 127t132 43q83 0 128.5-44t45.5-126q0-79-46-124.5T877-27q-85 0-131 44.5T700 143zm584 0q0 84 45 127t131 43q83 0 128.5-44t45.5-126q0-79-46-124.5T1460-27q-84 0-130 44.5T1284 143z"/><glyph horiz-adv-x="381"/><glyph unicode="‹" horiz-adv-x="754" d="M82 573l371 455 219-119-279-348 279-348L453 94 82 547v26z"/><glyph unicode="›" horiz-adv-x="754" d="M672 547L301 94 82 213l278 348L82 909l219 119 371-455v-26z"/><glyph unicode="⁄" horiz-adv-x="266" d="M657 1462L-154 0h-239l811 1462h239z"/><glyph horiz-adv-x="476"/><glyph unicode="⁴" horiz-adv-x="776" d="M758 737H633V586H395v151H12v154l385 577h236V905h125V737zM395 905v164q0 86 6 184-9-26-35.5-80t-41.5-77L197 905h198z"/><glyph unicode="€" d="M803 1225q-122 0-201-70.5T500 950h403V774H485l-2-35v-47l2-33h355V481H502q51-243 321-243 143 0 275 57V39Q982-20 805-20q-245 0-403 133T203 481H66v178h118q-4 23-4 62l2 53H66v176h133q37 242 199 382.5T803 1473q188 0 352-82l-98-232q-69 31-129 48.5T803 1225z"/><glyph unicode="™" horiz-adv-x="1534" d="M381 741H213v572H16v149h564v-149H381V741zm575 0l-165 529h-7l4-111V741H625v721h247l160-510 170 510h240V741h-168v408l4 121h-6l-174-529H956z"/><glyph unicode="" horiz-adv-x="1120" d="M0 1120h1120V0H0v1120z"/><glyph horiz-adv-x="1296" d="M0 0z"/><hkern u1="&quot;" u2="Ÿ" k="-20"/><hkern u1="&quot;" u2="œ" k="123"/><hkern u1="&quot;" u2="ü" k="61"/><hkern u1="&quot;" u2="û" k="61"/><hkern u1="&quot;" u2="ú" k="61"/><hkern u1="&quot;" u2="ù" k="61"/><hkern u1="&quot;" u2="ø" k="123"/><hkern u1="&quot;" u2="ö" k="123"/><hkern u1="&quot;" u2="õ" k="123"/><hkern u1="&quot;" u2="ô" k="123"/><hkern u1="&quot;" u2="ó" k="123"/><hkern u1="&quot;" u2="ò" k="123"/><hkern u1="&quot;" u2="ë" k="123"/><hkern u1="&quot;" u2="ê" k="123"/><hkern u1="&quot;" u2="é" k="123"/><hkern u1="&quot;" u2="è" k="123"/><hkern u1="&quot;" u2="ç" k="123"/><hkern u1="&quot;" u2="æ" k="82"/><hkern u1="&quot;" u2="å" k="82"/><hkern u1="&quot;" u2="ä" k="82"/><hkern u1="&quot;" u2="ã" k="82"/><hkern u1="&quot;" u2="â" k="82"/><hkern u1="&quot;" u2="á" k="82"/><hkern u1="&quot;" u2="à" k="123"/><hkern u1="&quot;" u2="Ý" k="-20"/><hkern u1="&quot;" u2="Å" k="143"/><hkern u1="&quot;" u2="Ä" k="143"/><hkern u1="&quot;" u2="Ã" k="143"/><hkern u1="&quot;" u2="Â" k="143"/><hkern u1="&quot;" u2="Á" k="143"/><hkern u1="&quot;" u2="À" k="143"/><hkern u1="&quot;" u2="u" k="61"/><hkern u1="&quot;" u2="s" k="61"/><hkern u1="&quot;" u2="r" k="61"/><hkern u1="&quot;" u2="q" k="123"/><hkern u1="&quot;" u2="p" k="61"/><hkern u1="&quot;" u2="o" k="123"/><hkern u1="&quot;" u2="n" k="61"/><hkern u1="&quot;" u2="m" k="61"/><hkern u1="&quot;" u2="g" k="61"/><hkern u1="&quot;" u2="e" k="123"/><hkern u1="&quot;" u2="d" k="123"/><hkern u1="&quot;" u2="c" k="123"/><hkern u1="&quot;" u2="a" k="82"/><hkern u1="&quot;" u2="Y" k="-20"/><hkern u1="&quot;" u2="W" k="-41"/><hkern u1="&quot;" u2="V" k="-41"/><hkern u1="&quot;" u2="T" k="-41"/><hkern u1="&quot;" u2="A" k="143"/><hkern u1="'" u2="Ÿ" k="-20"/><hkern u1="'" u2="œ" k="123"/><hkern u1="'" u2="ü" k="61"/><hkern u1="'" u2="û" k="61"/><hkern u1="'" u2="ú" k="61"/><hkern u1="'" u2="ù" k="61"/><hkern u1="'" u2="ø" k="123"/><hkern u1="'" u2="ö" k="123"/><hkern u1="'" u2="õ" k="123"/><hkern u1="'" u2="ô" k="123"/><hkern u1="'" u2="ó" k="123"/><hkern u1="'" u2="ò" k="123"/><hkern u1="'" u2="ë" k="123"/><hkern u1="'" u2="ê" k="123"/><hkern u1="'" u2="é" k="123"/><hkern u1="'" u2="è" k="123"/><hkern u1="'" u2="ç" k="123"/><hkern u1="'" u2="æ" k="82"/><hkern u1="'" u2="å" k="82"/><hkern u1="'" u2="ä" k="82"/><hkern u1="'" u2="ã" k="82"/><hkern u1="'" u2="â" k="82"/><hkern u1="'" u2="á" k="82"/><hkern u1="'" u2="à" k="123"/><hkern u1="'" u2="Ý" k="-20"/><hkern u1="'" u2="Å" k="143"/><hkern u1="'" u2="Ä" k="143"/><hkern u1="'" u2="Ã" k="143"/><hkern u1="'" u2="Â" k="143"/><hkern u1="'" u2="Á" k="143"/><hkern u1="'" u2="À" k="143"/><hkern u1="'" u2="u" k="61"/><hkern u1="'" u2="s" k="61"/><hkern u1="'" u2="r" k="61"/><hkern u1="'" u2="q" k="123"/><hkern u1="'" u2="p" k="61"/><hkern u1="'" u2="o" k="123"/><hkern u1="'" u2="n" k="61"/><hkern u1="'" u2="m" k="61"/><hkern u1="'" u2="g" k="61"/><hkern u1="'" u2="e" k="123"/><hkern u1="'" u2="d" k="123"/><hkern u1="'" u2="c" k="123"/><hkern u1="'" u2="a" k="82"/><hkern u1="'" u2="Y" k="-20"/><hkern u1="'" u2="W" k="-41"/><hkern u1="'" u2="V" k="-41"/><hkern u1="'" u2="T" k="-41"/><hkern u1="'" u2="A" k="143"/><hkern u1="(" u2="J" k="-184"/><hkern u1="," u2="Ÿ" k="123"/><hkern u1="," u2="Œ" k="102"/><hkern u1="," u2="Ý" k="123"/><hkern u1="," u2="Ü" k="41"/><hkern u1="," u2="Û" k="41"/><hkern u1="," u2="Ú" k="41"/><hkern u1="," u2="Ù" k="41"/><hkern u1="," u2="Ø" k="102"/><hkern u1="," u2="Ö" k="102"/><hkern u1="," u2="Õ" k="102"/><hkern u1="," u2="Ô" k="102"/><hkern u1="," u2="Ó" k="102"/><hkern u1="," u2="Ò" k="102"/><hkern u1="," u2="Ç" k="102"/><hkern u1="," u2="Y" k="123"/><hkern u1="," u2="W" k="123"/><hkern u1="," u2="V" k="123"/><hkern u1="," u2="U" k="41"/><hkern u1="," u2="T" k="143"/><hkern u1="," u2="Q" k="102"/><hkern u1="," u2="O" k="102"/><hkern u1="," u2="G" k="102"/><hkern u1="," u2="C" k="102"/><hkern u1="-" u2="T" k="82"/><hkern u1="." u2="Ÿ" k="123"/><hkern u1="." u2="Œ" k="102"/><hkern u1="." u2="Ý" k="123"/><hkern u1="." u2="Ü" k="41"/><hkern u1="." u2="Û" k="41"/><hkern u1="." u2="Ú" k="41"/><hkern u1="." u2="Ù" k="41"/><hkern u1="." u2="Ø" k="102"/><hkern u1="." u2="Ö" k="102"/><hkern u1="." u2="Õ" k="102"/><hkern u1="." u2="Ô" k="102"/><hkern u1="." u2="Ó" k="102"/><hkern u1="." u2="Ò" k="102"/><hkern u1="." u2="Ç" k="102"/><hkern u1="." u2="Y" k="123"/><hkern u1="." u2="W" k="123"/><hkern u1="." u2="V" k="123"/><hkern u1="." u2="U" k="41"/><hkern u1="." u2="T" k="143"/><hkern u1="." u2="Q" k="102"/><hkern u1="." u2="O" k="102"/><hkern u1="." u2="G" k="102"/><hkern u1="." u2="C" k="102"/><hkern u1="A" u2="”" k="143"/><hkern u1="A" u2="’" k="143"/><hkern u1="A" u2="Ÿ" k="123"/><hkern u1="A" u2="Œ" k="41"/><hkern u1="A" u2="Ý" k="123"/><hkern u1="A" u2="Ø" k="41"/><hkern u1="A" u2="Ö" k="41"/><hkern u1="A" u2="Õ" k="41"/><hkern u1="A" u2="Ô" k="41"/><hkern u1="A" u2="Ó" k="41"/><hkern u1="A" u2="Ò" k="41"/><hkern u1="A" u2="Ç" k="41"/><hkern u1="A" u2="Y" k="123"/><hkern u1="A" u2="W" k="82"/><hkern u1="A" u2="V" k="82"/><hkern u1="A" u2="T" k="143"/><hkern u1="A" u2="Q" k="41"/><hkern u1="A" u2="O" k="41"/><hkern u1="A" u2="J" k="-266"/><hkern u1="A" u2="G" k="41"/><hkern u1="A" u2="C" k="41"/><hkern u1="A" u2="'" k="143"/><hkern u1="A" u2="&quot;" k="143"/><hkern u1="B" u2="„" k="82"/><hkern u1="B" u2="‚" k="82"/><hkern u1="B" u2="Ÿ" k="20"/><hkern u1="B" u2="Ý" k="20"/><hkern u1="B" u2="Å" k="41"/><hkern u1="B" u2="Ä" k="41"/><hkern u1="B" u2="Ã" k="41"/><hkern u1="B" u2="Â" k="41"/><hkern u1="B" u2="Á" k="41"/><hkern u1="B" u2="À" k="41"/><hkern u1="B" u2="Z" k="20"/><hkern u1="B" u2="Y" k="20"/><hkern u1="B" u2="X" k="41"/><hkern u1="B" u2="W" k="20"/><hkern u1="B" u2="V" k="20"/><hkern u1="B" u2="T" k="61"/><hkern u1="B" u2="A" k="41"/><hkern u1="B" u2="." k="82"/><hkern u1="B" u2="," k="82"/><hkern u1="C" u2="Œ" k="41"/><hkern u1="C" u2="Ø" k="41"/><hkern u1="C" u2="Ö" k="41"/><hkern u1="C" u2="Õ" k="41"/><hkern u1="C" u2="Ô" k="41"/><hkern u1="C" u2="Ó" k="41"/><hkern u1="C" u2="Ò" k="41"/><hkern u1="C" u2="Ç" k="41"/><hkern u1="C" u2="Q" k="41"/><hkern u1="C" u2="O" k="41"/><hkern u1="C" u2="G" k="41"/><hkern u1="C" u2="C" k="41"/><hkern u1="D" u2="„" k="82"/><hkern u1="D" u2="‚" k="82"/><hkern u1="D" u2="Ÿ" k="20"/><hkern u1="D" u2="Ý" k="20"/><hkern u1="D" u2="Å" k="41"/><hkern u1="D" u2="Ä" k="41"/><hkern u1="D" u2="Ã" k="41"/><hkern u1="D" u2="Â" k="41"/><hkern u1="D" u2="Á" k="41"/><hkern u1="D" u2="À" k="41"/><hkern u1="D" u2="Z" k="20"/><hkern u1="D" u2="Y" k="20"/><hkern u1="D" u2="X" k="41"/><hkern u1="D" u2="W" k="20"/><hkern u1="D" u2="V" k="20"/><hkern u1="D" u2="T" k="61"/><hkern u1="D" u2="A" k="41"/><hkern u1="D" u2="." k="82"/><hkern u1="D" u2="," k="82"/><hkern u1="E" u2="J" k="-123"/><hkern u1="F" u2="„" k="123"/><hkern u1="F" u2="‚" k="123"/><hkern u1="F" u2="Å" k="41"/><hkern u1="F" u2="Ä" k="41"/><hkern u1="F" u2="Ã" k="41"/><hkern u1="F" u2="Â" k="41"/><hkern u1="F" u2="Á" k="41"/><hkern u1="F" u2="À" k="41"/><hkern u1="F" u2="A" k="41"/><hkern u1="F" u2="?" k="-41"/><hkern u1="F" u2="." k="123"/><hkern u1="F" u2="," k="123"/><hkern u1="K" u2="Œ" k="41"/><hkern u1="K" u2="Ø" k="41"/><hkern u1="K" u2="Ö" k="41"/><hkern u1="K" u2="Õ" k="41"/><hkern u1="K" u2="Ô" k="41"/><hkern u1="K" u2="Ó" k="41"/><hkern u1="K" u2="Ò" k="41"/><hkern u1="K" u2="Ç" k="41"/><hkern u1="K" u2="Q" k="41"/><hkern u1="K" u2="O" k="41"/><hkern u1="K" u2="G" k="41"/><hkern u1="K" u2="C" k="41"/><hkern u1="L" u2="”" k="164"/><hkern u1="L" u2="’" k="164"/><hkern u1="L" u2="Ÿ" k="61"/><hkern u1="L" u2="Œ" k="41"/><hkern u1="L" u2="Ý" k="61"/><hkern u1="L" u2="Ü" k="20"/><hkern u1="L" u2="Û" k="20"/><hkern u1="L" u2="Ú" k="20"/><hkern u1="L" u2="Ù" k="20"/><hkern u1="L" u2="Ø" k="41"/><hkern u1="L" u2="Ö" k="41"/><hkern u1="L" u2="Õ" k="41"/><hkern u1="L" u2="Ô" k="41"/><hkern u1="L" u2="Ó" k="41"/><hkern u1="L" u2="Ò" k="41"/><hkern u1="L" u2="Ç" k="41"/><hkern u1="L" u2="Y" k="61"/><hkern u1="L" u2="W" k="41"/><hkern u1="L" u2="V" k="41"/><hkern u1="L" u2="U" k="20"/><hkern u1="L" u2="T" k="41"/><hkern u1="L" u2="Q" k="41"/><hkern u1="L" u2="O" k="41"/><hkern u1="L" u2="G" k="41"/><hkern u1="L" u2="C" k="41"/><hkern u1="L" u2="'" k="164"/><hkern u1="L" u2="&quot;" k="164"/><hkern u1="O" u2="„" k="82"/><hkern u1="O" u2="‚" k="82"/><hkern u1="O" u2="Ÿ" k="20"/><hkern u1="O" u2="Ý" k="20"/><hkern u1="O" u2="Å" k="41"/><hkern u1="O" u2="Ä" k="41"/><hkern u1="O" u2="Ã" k="41"/><hkern u1="O" u2="Â" k="41"/><hkern u1="O" u2="Á" k="41"/><hkern u1="O" u2="À" k="41"/><hkern u1="O" u2="Z" k="20"/><hkern u1="O" u2="Y" k="20"/><hkern u1="O" u2="X" k="41"/><hkern u1="O" u2="W" k="20"/><hkern u1="O" u2="V" k="20"/><hkern u1="O" u2="T" k="61"/><hkern u1="O" u2="A" k="41"/><hkern u1="O" u2="." k="82"/><hkern u1="O" u2="," k="82"/><hkern u1="P" u2="„" k="266"/><hkern u1="P" u2="‚" k="266"/><hkern u1="P" u2="Å" k="102"/><hkern u1="P" u2="Ä" k="102"/><hkern u1="P" u2="Ã" k="102"/><hkern u1="P" u2="Â" k="102"/><hkern u1="P" u2="Á" k="102"/><hkern u1="P" u2="À" k="102"/><hkern u1="P" u2="Z" k="20"/><hkern u1="P" u2="X" k="41"/><hkern u1="P" u2="A" k="102"/><hkern u1="P" u2="." k="266"/><hkern u1="P" u2="," k="266"/><hkern u1="Q" u2="„" k="82"/><hkern u1="Q" u2="‚" k="82"/><hkern u1="Q" u2="Ÿ" k="20"/><hkern u1="Q" u2="Ý" k="20"/><hkern u1="Q" u2="Å" k="41"/><hkern u1="Q" u2="Ä" k="41"/><hkern u1="Q" u2="Ã" k="41"/><hkern u1="Q" u2="Â" k="41"/><hkern u1="Q" u2="Á" k="41"/><hkern u1="Q" u2="À" k="41"/><hkern u1="Q" u2="Z" k="20"/><hkern u1="Q" u2="Y" k="20"/><hkern u1="Q" u2="X" k="41"/><hkern u1="Q" u2="W" k="20"/><hkern u1="Q" u2="V" k="20"/><hkern u1="Q" u2="T" k="61"/><hkern u1="Q" u2="A" k="41"/><hkern u1="Q" u2="." k="82"/><hkern u1="Q" u2="," k="82"/><hkern u1="T" u2="„" k="123"/><hkern u1="T" u2="‚" k="123"/><hkern u1="T" u2="—" k="82"/><hkern u1="T" u2="–" k="82"/><hkern u1="T" u2="œ" k="143"/><hkern u1="T" u2="Œ" k="41"/><hkern u1="T" u2="ý" k="41"/><hkern u1="T" u2="ü" k="102"/><hkern u1="T" u2="û" k="102"/><hkern u1="T" u2="ú" k="102"/><hkern u1="T" u2="ù" k="102"/><hkern u1="T" u2="ø" k="143"/><hkern u1="T" u2="ö" k="143"/><hkern u1="T" u2="õ" k="143"/><hkern u1="T" u2="ô" k="143"/><hkern u1="T" u2="ó" k="143"/><hkern u1="T" u2="ò" k="143"/><hkern u1="T" u2="ë" k="143"/><hkern u1="T" u2="ê" k="143"/><hkern u1="T" u2="é" k="143"/><hkern u1="T" u2="è" k="143"/><hkern u1="T" u2="ç" k="143"/><hkern u1="T" u2="æ" k="164"/><hkern u1="T" u2="å" k="164"/><hkern u1="T" u2="ä" k="164"/><hkern u1="T" u2="ã" k="164"/><hkern u1="T" u2="â" k="164"/><hkern u1="T" u2="á" k="164"/><hkern u1="T" u2="à" k="143"/><hkern u1="T" u2="Ø" k="41"/><hkern u1="T" u2="Ö" k="41"/><hkern u1="T" u2="Õ" k="41"/><hkern u1="T" u2="Ô" k="41"/><hkern u1="T" u2="Ó" k="41"/><hkern u1="T" u2="Ò" k="41"/><hkern u1="T" u2="Ç" k="41"/><hkern u1="T" u2="Å" k="143"/><hkern u1="T" u2="Ä" k="143"/><hkern u1="T" u2="Ã" k="143"/><hkern u1="T" u2="Â" k="143"/><hkern u1="T" u2="Á" k="143"/><hkern u1="T" u2="À" k="143"/><hkern u1="T" u2="z" k="82"/><hkern u1="T" u2="y" k="41"/><hkern u1="T" u2="x" k="41"/><hkern u1="T" u2="w" k="41"/><hkern u1="T" u2="v" k="41"/><hkern u1="T" u2="u" k="102"/><hkern u1="T" u2="s" k="123"/><hkern u1="T" u2="r" k="102"/><hkern u1="T" u2="q" k="143"/><hkern u1="T" u2="p" k="102"/><hkern u1="T" u2="o" k="143"/><hkern u1="T" u2="n" k="102"/><hkern u1="T" u2="m" k="102"/><hkern u1="T" u2="g" k="143"/><hkern u1="T" u2="e" k="143"/><hkern u1="T" u2="d" k="143"/><hkern u1="T" u2="c" k="143"/><hkern u1="T" u2="a" k="164"/><hkern u1="T" u2="T" k="-41"/><hkern u1="T" u2="Q" k="41"/><hkern u1="T" u2="O" k="41"/><hkern u1="T" u2="G" k="41"/><hkern u1="T" u2="C" k="41"/><hkern u1="T" u2="A" k="143"/><hkern u1="T" u2="?" k="-41"/><hkern u1="T" u2="." k="123"/><hkern u1="T" u2="-" k="82"/><hkern u1="T" u2="," k="123"/><hkern u1="U" u2="„" k="41"/><hkern u1="U" u2="‚" k="41"/><hkern u1="U" u2="Å" k="20"/><hkern u1="U" u2="Ä" k="20"/><hkern u1="U" u2="Ã" k="20"/><hkern u1="U" u2="Â" k="20"/><hkern u1="U" u2="Á" k="20"/><hkern u1="U" u2="À" k="20"/><hkern u1="U" u2="A" k="20"/><hkern u1="U" u2="." k="41"/><hkern u1="U" u2="," k="41"/><hkern u1="V" u2="„" k="102"/><hkern u1="V" u2="‚" k="102"/><hkern u1="V" u2="œ" k="41"/><hkern u1="V" u2="Œ" k="20"/><hkern u1="V" u2="ü" k="20"/><hkern u1="V" u2="û" k="20"/><hkern u1="V" u2="ú" k="20"/><hkern u1="V" u2="ù" k="20"/><hkern u1="V" u2="ø" k="41"/><hkern u1="V" u2="ö" k="41"/><hkern u1="V" u2="õ" k="41"/><hkern u1="V" u2="ô" k="41"/><hkern u1="V" u2="ó" k="41"/><hkern u1="V" u2="ò" k="41"/><hkern u1="V" u2="ë" k="41"/><hkern u1="V" u2="ê" k="41"/><hkern u1="V" u2="é" k="41"/><hkern u1="V" u2="è" k="41"/><hkern u1="V" u2="ç" k="41"/><hkern u1="V" u2="æ" k="41"/><hkern u1="V" u2="å" k="41"/><hkern u1="V" u2="ä" k="41"/><hkern u1="V" u2="ã" k="41"/><hkern u1="V" u2="â" k="41"/><hkern u1="V" u2="á" k="41"/><hkern u1="V" u2="à" k="41"/><hkern u1="V" u2="Ø" k="20"/><hkern u1="V" u2="Ö" k="20"/><hkern u1="V" u2="Õ" k="20"/><hkern u1="V" u2="Ô" k="20"/><hkern u1="V" u2="Ó" k="20"/><hkern u1="V" u2="Ò" k="20"/><hkern u1="V" u2="Ç" k="20"/><hkern u1="V" u2="Å" k="82"/><hkern u1="V" u2="Ä" k="82"/><hkern u1="V" u2="Ã" k="82"/><hkern u1="V" u2="Â" k="82"/><hkern u1="V" u2="Á" k="82"/><hkern u1="V" u2="À" k="82"/><hkern u1="V" u2="u" k="20"/><hkern u1="V" u2="s" k="20"/><hkern u1="V" u2="r" k="20"/><hkern u1="V" u2="q" k="41"/><hkern u1="V" u2="p" k="20"/><hkern u1="V" u2="o" k="41"/><hkern u1="V" u2="n" k="20"/><hkern u1="V" u2="m" k="20"/><hkern u1="V" u2="g" k="20"/><hkern u1="V" u2="e" k="41"/><hkern u1="V" u2="d" k="41"/><hkern u1="V" u2="c" k="41"/><hkern u1="V" u2="a" k="41"/><hkern u1="V" u2="Q" k="20"/><hkern u1="V" u2="O" k="20"/><hkern u1="V" u2="G" k="20"/><hkern u1="V" u2="C" k="20"/><hkern u1="V" u2="A" k="82"/><hkern u1="V" u2="?" k="-41"/><hkern u1="V" u2="." k="102"/><hkern u1="V" u2="," k="102"/><hkern u1="W" u2="„" k="102"/><hkern u1="W" u2="‚" k="102"/><hkern u1="W" u2="œ" k="41"/><hkern u1="W" u2="Œ" k="20"/><hkern u1="W" u2="ü" k="20"/><hkern u1="W" u2="û" k="20"/><hkern u1="W" u2="ú" k="20"/><hkern u1="W" u2="ù" k="20"/><hkern u1="W" u2="ø" k="41"/><hkern u1="W" u2="ö" k="41"/><hkern u1="W" u2="õ" k="41"/><hkern u1="W" u2="ô" k="41"/><hkern u1="W" u2="ó" k="41"/><hkern u1="W" u2="ò" k="41"/><hkern u1="W" u2="ë" k="41"/><hkern u1="W" u2="ê" k="41"/><hkern u1="W" u2="é" k="41"/><hkern u1="W" u2="è" k="41"/><hkern u1="W" u2="ç" k="41"/><hkern u1="W" u2="æ" k="41"/><hkern u1="W" u2="å" k="41"/><hkern u1="W" u2="ä" k="41"/><hkern u1="W" u2="ã" k="41"/><hkern u1="W" u2="â" k="41"/><hkern u1="W" u2="á" k="41"/><hkern u1="W" u2="à" k="41"/><hkern u1="W" u2="Ø" k="20"/><hkern u1="W" u2="Ö" k="20"/><hkern u1="W" u2="Õ" k="20"/><hkern u1="W" u2="Ô" k="20"/><hkern u1="W" u2="Ó" k="20"/><hkern u1="W" u2="Ò" k="20"/><hkern u1="W" u2="Ç" k="20"/><hkern u1="W" u2="Å" k="82"/><hkern u1="W" u2="Ä" k="82"/><hkern u1="W" u2="Ã" k="82"/><hkern u1="W" u2="Â" k="82"/><hkern u1="W" u2="Á" k="82"/><hkern u1="W" u2="À" k="82"/><hkern u1="W" u2="u" k="20"/><hkern u1="W" u2="s" k="20"/><hkern u1="W" u2="r" k="20"/><hkern u1="W" u2="q" k="41"/><hkern u1="W" u2="p" k="20"/><hkern u1="W" u2="o" k="41"/><hkern u1="W" u2="n" k="20"/><hkern u1="W" u2="m" k="20"/><hkern u1="W" u2="g" k="20"/><hkern u1="W" u2="e" k="41"/><hkern u1="W" u2="d" k="41"/><hkern u1="W" u2="c" k="41"/><hkern u1="W" u2="a" k="41"/><hkern u1="W" u2="Q" k="20"/><hkern u1="W" u2="O" k="20"/><hkern u1="W" u2="G" k="20"/><hkern u1="W" u2="C" k="20"/><hkern u1="W" u2="A" k="82"/><hkern u1="W" u2="?" k="-41"/><hkern u1="W" u2="." k="102"/><hkern u1="W" u2="," k="102"/><hkern u1="X" u2="Œ" k="41"/><hkern u1="X" u2="Ø" k="41"/><hkern u1="X" u2="Ö" k="41"/><hkern u1="X" u2="Õ" k="41"/><hkern u1="X" u2="Ô" k="41"/><hkern u1="X" u2="Ó" k="41"/><hkern u1="X" u2="Ò" k="41"/><hkern u1="X" u2="Ç" k="41"/><hkern u1="X" u2="Q" k="41"/><hkern u1="X" u2="O" k="41"/><hkern u1="X" u2="G" k="41"/><hkern u1="X" u2="C" k="41"/><hkern u1="Y" u2="„" k="123"/><hkern u1="Y" u2="‚" k="123"/><hkern u1="Y" u2="œ" k="102"/><hkern u1="Y" u2="Œ" k="41"/><hkern u1="Y" u2="ü" k="61"/><hkern u1="Y" u2="û" k="61"/><hkern u1="Y" u2="ú" k="61"/><hkern u1="Y" u2="ù" k="61"/><hkern u1="Y" u2="ø" k="102"/><hkern u1="Y" u2="ö" k="102"/><hkern u1="Y" u2="õ" k="102"/><hkern u1="Y" u2="ô" k="102"/><hkern u1="Y" u2="ó" k="102"/><hkern u1="Y" u2="ò" k="102"/><hkern u1="Y" u2="ë" k="102"/><hkern u1="Y" u2="ê" k="102"/><hkern u1="Y" u2="é" k="102"/><hkern u1="Y" u2="è" k="102"/><hkern u1="Y" u2="ç" k="102"/><hkern u1="Y" u2="æ" k="102"/><hkern u1="Y" u2="å" k="102"/><hkern u1="Y" u2="ä" k="102"/><hkern u1="Y" u2="ã" k="102"/><hkern u1="Y" u2="â" k="102"/><hkern u1="Y" u2="á" k="102"/><hkern u1="Y" u2="à" k="102"/><hkern u1="Y" u2="Ø" k="41"/><hkern u1="Y" u2="Ö" k="41"/><hkern u1="Y" u2="Õ" k="41"/><hkern u1="Y" u2="Ô" k="41"/><hkern u1="Y" u2="Ó" k="41"/><hkern u1="Y" u2="Ò" k="41"/><hkern u1="Y" u2="Ç" k="41"/><hkern u1="Y" u2="Å" k="123"/><hkern u1="Y" u2="Ä" k="123"/><hkern u1="Y" u2="Ã" k="123"/><hkern u1="Y" u2="Â" k="123"/><hkern u1="Y" u2="Á" k="123"/><hkern u1="Y" u2="À" k="123"/><hkern u1="Y" u2="z" k="41"/><hkern u1="Y" u2="u" k="61"/><hkern u1="Y" u2="s" k="82"/><hkern u1="Y" u2="r" k="61"/><hkern u1="Y" u2="q" k="102"/><hkern u1="Y" u2="p" k="61"/><hkern u1="Y" u2="o" k="102"/><hkern u1="Y" u2="n" k="61"/><hkern u1="Y" u2="m" k="61"/><hkern u1="Y" u2="g" k="41"/><hkern u1="Y" u2="e" k="102"/><hkern u1="Y" u2="d" k="102"/><hkern u1="Y" u2="c" k="102"/><hkern u1="Y" u2="a" k="102"/><hkern u1="Y" u2="Q" k="41"/><hkern u1="Y" u2="O" k="41"/><hkern u1="Y" u2="G" k="41"/><hkern u1="Y" u2="C" k="41"/><hkern u1="Y" u2="A" k="123"/><hkern u1="Y" u2="?" k="-41"/><hkern u1="Y" u2="." k="123"/><hkern u1="Y" u2="," k="123"/><hkern u1="Z" u2="Œ" k="20"/><hkern u1="Z" u2="Ø" k="20"/><hkern u1="Z" u2="Ö" k="20"/><hkern u1="Z" u2="Õ" k="20"/><hkern u1="Z" u2="Ô" k="20"/><hkern u1="Z" u2="Ó" k="20"/><hkern u1="Z" u2="Ò" k="20"/><hkern u1="Z" u2="Ç" k="20"/><hkern u1="Z" u2="Q" k="20"/><hkern u1="Z" u2="O" k="20"/><hkern u1="Z" u2="G" k="20"/><hkern u1="Z" u2="C" k="20"/><hkern u1="[" u2="J" k="-184"/><hkern u1="a" u2="”" k="20"/><hkern u1="a" u2="’" k="20"/><hkern u1="a" u2="'" k="20"/><hkern u1="a" u2="&quot;" k="20"/><hkern u1="b" u2="”" k="20"/><hkern u1="b" u2="’" k="20"/><hkern u1="b" u2="ý" k="41"/><hkern u1="b" u2="z" k="20"/><hkern u1="b" u2="y" k="41"/><hkern u1="b" u2="x" k="41"/><hkern u1="b" u2="w" k="41"/><hkern u1="b" u2="v" k="41"/><hkern u1="b" u2="'" k="20"/><hkern u1="b" u2="&quot;" k="20"/><hkern u1="c" u2="”" k="-41"/><hkern u1="c" u2="’" k="-41"/><hkern u1="c" u2="'" k="-41"/><hkern u1="c" u2="&quot;" k="-41"/><hkern u1="e" u2="”" k="20"/><hkern u1="e" u2="’" k="20"/><hkern u1="e" u2="ý" k="41"/><hkern u1="e" u2="z" k="20"/><hkern u1="e" u2="y" k="41"/><hkern u1="e" u2="x" k="41"/><hkern u1="e" u2="w" k="41"/><hkern u1="e" u2="v" k="41"/><hkern u1="e" u2="'" k="20"/><hkern u1="e" u2="&quot;" k="20"/><hkern u1="f" u2="”" k="-123"/><hkern u1="f" u2="’" k="-123"/><hkern u1="f" u2="'" k="-123"/><hkern u1="f" u2="&quot;" k="-123"/><hkern u1="h" u2="”" k="20"/><hkern u1="h" u2="’" k="20"/><hkern u1="h" u2="'" k="20"/><hkern u1="h" u2="&quot;" k="20"/><hkern u1="k" u2="œ" k="41"/><hkern u1="k" u2="ø" k="41"/><hkern u1="k" u2="ö" k="41"/><hkern u1="k" u2="õ" k="41"/><hkern u1="k" u2="ô" k="41"/><hkern u1="k" u2="ó" k="41"/><hkern u1="k" u2="ò" k="41"/><hkern u1="k" u2="ë" k="41"/><hkern u1="k" u2="ê" k="41"/><hkern u1="k" u2="é" k="41"/><hkern u1="k" u2="è" k="41"/><hkern u1="k" u2="ç" k="41"/><hkern u1="k" u2="à" k="41"/><hkern u1="k" u2="q" k="41"/><hkern u1="k" u2="o" k="41"/><hkern u1="k" u2="e" k="41"/><hkern u1="k" u2="d" k="41"/><hkern u1="k" u2="c" k="41"/><hkern u1="m" u2="”" k="20"/><hkern u1="m" u2="’" k="20"/><hkern u1="m" u2="'" k="20"/><hkern u1="m" u2="&quot;" k="20"/><hkern u1="n" u2="”" k="20"/><hkern u1="n" u2="’" k="20"/><hkern u1="n" u2="'" k="20"/><hkern u1="n" u2="&quot;" k="20"/><hkern u1="o" u2="”" k="20"/><hkern u1="o" u2="’" k="20"/><hkern u1="o" u2="ý" k="41"/><hkern u1="o" u2="z" k="20"/><hkern u1="o" u2="y" k="41"/><hkern u1="o" u2="x" k="41"/><hkern u1="o" u2="w" k="41"/><hkern u1="o" u2="v" k="41"/><hkern u1="o" u2="'" k="20"/><hkern u1="o" u2="&quot;" k="20"/><hkern u1="p" u2="”" k="20"/><hkern u1="p" u2="’" k="20"/><hkern u1="p" u2="ý" k="41"/><hkern u1="p" u2="z" k="20"/><hkern u1="p" u2="y" k="41"/><hkern u1="p" u2="x" k="41"/><hkern u1="p" u2="w" k="41"/><hkern u1="p" u2="v" k="41"/><hkern u1="p" u2="'" k="20"/><hkern u1="p" u2="&quot;" k="20"/><hkern u1="r" u2="”" k="-82"/><hkern u1="r" u2="’" k="-82"/><hkern u1="r" u2="œ" k="41"/><hkern u1="r" u2="ø" k="41"/><hkern u1="r" u2="ö" k="41"/><hkern u1="r" u2="õ" k="41"/><hkern u1="r" u2="ô" k="41"/><hkern u1="r" u2="ó" k="41"/><hkern u1="r" u2="ò" k="41"/><hkern u1="r" u2="ë" k="41"/><hkern u1="r" u2="ê" k="41"/><hkern u1="r" u2="é" k="41"/><hkern u1="r" u2="è" k="41"/><hkern u1="r" u2="ç" k="41"/><hkern u1="r" u2="æ" k="41"/><hkern u1="r" u2="å" k="41"/><hkern u1="r" u2="ä" k="41"/><hkern u1="r" u2="ã" k="41"/><hkern u1="r" u2="â" k="41"/><hkern u1="r" u2="á" k="41"/><hkern u1="r" u2="à" k="41"/><hkern u1="r" u2="q" k="41"/><hkern u1="r" u2="o" k="41"/><hkern u1="r" u2="g" k="20"/><hkern u1="r" u2="e" k="41"/><hkern u1="r" u2="d" k="41"/><hkern u1="r" u2="c" k="41"/><hkern u1="r" u2="a" k="41"/><hkern u1="r" u2="'" k="-82"/><hkern u1="r" u2="&quot;" k="-82"/><hkern u1="t" u2="”" k="-41"/><hkern u1="t" u2="’" k="-41"/><hkern u1="t" u2="'" k="-41"/><hkern u1="t" u2="&quot;" k="-41"/><hkern u1="v" u2="„" k="82"/><hkern u1="v" u2="”" k="-82"/><hkern u1="v" u2="‚" k="82"/><hkern u1="v" u2="’" k="-82"/><hkern u1="v" u2="?" k="-41"/><hkern u1="v" u2="." k="82"/><hkern u1="v" u2="," k="82"/><hkern u1="v" u2="'" k="-82"/><hkern u1="v" u2="&quot;" k="-82"/><hkern u1="w" u2="„" k="82"/><hkern u1="w" u2="”" k="-82"/><hkern u1="w" u2="‚" k="82"/><hkern u1="w" u2="’" k="-82"/><hkern u1="w" u2="?" k="-41"/><hkern u1="w" u2="." k="82"/><hkern u1="w" u2="," k="82"/><hkern u1="w" u2="'" k="-82"/><hkern u1="w" u2="&quot;" k="-82"/><hkern u1="x" u2="œ" k="41"/><hkern u1="x" u2="ø" k="41"/><hkern u1="x" u2="ö" k="41"/><hkern u1="x" u2="õ" k="41"/><hkern u1="x" u2="ô" k="41"/><hkern u1="x" u2="ó" k="41"/><hkern u1="x" u2="ò" k="41"/><hkern u1="x" u2="ë" k="41"/><hkern u1="x" u2="ê" k="41"/><hkern u1="x" u2="é" k="41"/><hkern u1="x" u2="è" k="41"/><hkern u1="x" u2="ç" k="41"/><hkern u1="x" u2="à" k="41"/><hkern u1="x" u2="q" k="41"/><hkern u1="x" u2="o" k="41"/><hkern u1="x" u2="e" k="41"/><hkern u1="x" u2="d" k="41"/><hkern u1="x" u2="c" k="41"/><hkern u1="y" u2="„" k="82"/><hkern u1="y" u2="”" k="-82"/><hkern u1="y" u2="‚" k="82"/><hkern u1="y" u2="’" k="-82"/><hkern u1="y" u2="?" k="-41"/><hkern u1="y" u2="." k="82"/><hkern u1="y" u2="," k="82"/><hkern u1="y" u2="'" k="-82"/><hkern u1="y" u2="&quot;" k="-82"/><hkern u1="{" u2="J" k="-184"/><hkern u1="À" u2="”" k="143"/><hkern u1="À" u2="’" k="143"/><hkern u1="À" u2="Ÿ" k="123"/><hkern u1="À" u2="Œ" k="41"/><hkern u1="À" u2="Ý" k="123"/><hkern u1="À" u2="Ø" k="41"/><hkern u1="À" u2="Ö" k="41"/><hkern u1="À" u2="Õ" k="41"/><hkern u1="À" u2="Ô" k="41"/><hkern u1="À" u2="Ó" k="41"/><hkern u1="À" u2="Ò" k="41"/><hkern u1="À" u2="Ç" k="41"/><hkern u1="À" u2="Y" k="123"/><hkern u1="À" u2="W" k="82"/><hkern u1="À" u2="V" k="82"/><hkern u1="À" u2="T" k="143"/><hkern u1="À" u2="Q" k="41"/><hkern u1="À" u2="O" k="41"/><hkern u1="À" u2="J" k="-266"/><hkern u1="À" u2="G" k="41"/><hkern u1="À" u2="C" k="41"/><hkern u1="À" u2="'" k="143"/><hkern u1="À" u2="&quot;" k="143"/><hkern u1="Á" u2="”" k="143"/><hkern u1="Á" u2="’" k="143"/><hkern u1="Á" u2="Ÿ" k="123"/><hkern u1="Á" u2="Œ" k="41"/><hkern u1="Á" u2="Ý" k="123"/><hkern u1="Á" u2="Ø" k="41"/><hkern u1="Á" u2="Ö" k="41"/><hkern u1="Á" u2="Õ" k="41"/><hkern u1="Á" u2="Ô" k="41"/><hkern u1="Á" u2="Ó" k="41"/><hkern u1="Á" u2="Ò" k="41"/><hkern u1="Á" u2="Ç" k="41"/><hkern u1="Á" u2="Y" k="123"/><hkern u1="Á" u2="W" k="82"/><hkern u1="Á" u2="V" k="82"/><hkern u1="Á" u2="T" k="143"/><hkern u1="Á" u2="Q" k="41"/><hkern u1="Á" u2="O" k="41"/><hkern u1="Á" u2="J" k="-266"/><hkern u1="Á" u2="G" k="41"/><hkern u1="Á" u2="C" k="41"/><hkern u1="Á" u2="'" k="143"/><hkern u1="Á" u2="&quot;" k="143"/><hkern u1="Â" u2="”" k="143"/><hkern u1="Â" u2="’" k="143"/><hkern u1="Â" u2="Ÿ" k="123"/><hkern u1="Â" u2="Œ" k="41"/><hkern u1="Â" u2="Ý" k="123"/><hkern u1="Â" u2="Ø" k="41"/><hkern u1="Â" u2="Ö" k="41"/><hkern u1="Â" u2="Õ" k="41"/><hkern u1="Â" u2="Ô" k="41"/><hkern u1="Â" u2="Ó" k="41"/><hkern u1="Â" u2="Ò" k="41"/><hkern u1="Â" u2="Ç" k="41"/><hkern u1="Â" u2="Y" k="123"/><hkern u1="Â" u2="W" k="82"/><hkern u1="Â" u2="V" k="82"/><hkern u1="Â" u2="T" k="143"/><hkern u1="Â" u2="Q" k="41"/><hkern u1="Â" u2="O" k="41"/><hkern u1="Â" u2="J" k="-266"/><hkern u1="Â" u2="G" k="41"/><hkern u1="Â" u2="C" k="41"/><hkern u1="Â" u2="'" k="143"/><hkern u1="Â" u2="&quot;" k="143"/><hkern u1="Ã" u2="”" k="143"/><hkern u1="Ã" u2="’" k="143"/><hkern u1="Ã" u2="Ÿ" k="123"/><hkern u1="Ã" u2="Œ" k="41"/><hkern u1="Ã" u2="Ý" k="123"/><hkern u1="Ã" u2="Ø" k="41"/><hkern u1="Ã" u2="Ö" k="41"/><hkern u1="Ã" u2="Õ" k="41"/><hkern u1="Ã" u2="Ô" k="41"/><hkern u1="Ã" u2="Ó" k="41"/><hkern u1="Ã" u2="Ò" k="41"/><hkern u1="Ã" u2="Ç" k="41"/><hkern u1="Ã" u2="Y" k="123"/><hkern u1="Ã" u2="W" k="82"/><hkern u1="Ã" u2="V" k="82"/><hkern u1="Ã" u2="T" k="143"/><hkern u1="Ã" u2="Q" k="41"/><hkern u1="Ã" u2="O" k="41"/><hkern u1="Ã" u2="J" k="-266"/><hkern u1="Ã" u2="G" k="41"/><hkern u1="Ã" u2="C" k="41"/><hkern u1="Ã" u2="'" k="143"/><hkern u1="Ã" u2="&quot;" k="143"/><hkern u1="Ä" u2="”" k="143"/><hkern u1="Ä" u2="’" k="143"/><hkern u1="Ä" u2="Ÿ" k="123"/><hkern u1="Ä" u2="Œ" k="41"/><hkern u1="Ä" u2="Ý" k="123"/><hkern u1="Ä" u2="Ø" k="41"/><hkern u1="Ä" u2="Ö" k="41"/><hkern u1="Ä" u2="Õ" k="41"/><hkern u1="Ä" u2="Ô" k="41"/><hkern u1="Ä" u2="Ó" k="41"/><hkern u1="Ä" u2="Ò" k="41"/><hkern u1="Ä" u2="Ç" k="41"/><hkern u1="Ä" u2="Y" k="123"/><hkern u1="Ä" u2="W" k="82"/><hkern u1="Ä" u2="V" k="82"/><hkern u1="Ä" u2="T" k="143"/><hkern u1="Ä" u2="Q" k="41"/><hkern u1="Ä" u2="O" k="41"/><hkern u1="Ä" u2="J" k="-266"/><hkern u1="Ä" u2="G" k="41"/><hkern u1="Ä" u2="C" k="41"/><hkern u1="Ä" u2="'" k="143"/><hkern u1="Ä" u2="&quot;" k="143"/><hkern u1="Å" u2="”" k="143"/><hkern u1="Å" u2="’" k="143"/><hkern u1="Å" u2="Ÿ" k="123"/><hkern u1="Å" u2="Œ" k="41"/><hkern u1="Å" u2="Ý" k="123"/><hkern u1="Å" u2="Ø" k="41"/><hkern u1="Å" u2="Ö" k="41"/><hkern u1="Å" u2="Õ" k="41"/><hkern u1="Å" u2="Ô" k="41"/><hkern u1="Å" u2="Ó" k="41"/><hkern u1="Å" u2="Ò" k="41"/><hkern u1="Å" u2="Ç" k="41"/><hkern u1="Å" u2="Y" k="123"/><hkern u1="Å" u2="W" k="82"/><hkern u1="Å" u2="V" k="82"/><hkern u1="Å" u2="T" k="143"/><hkern u1="Å" u2="Q" k="41"/><hkern u1="Å" u2="O" k="41"/><hkern u1="Å" u2="J" k="-266"/><hkern u1="Å" u2="G" k="41"/><hkern u1="Å" u2="C" k="41"/><hkern u1="Å" u2="'" k="143"/><hkern u1="Å" u2="&quot;" k="143"/><hkern u1="Æ" u2="J" k="-123"/><hkern u1="Ç" u2="Œ" k="41"/><hkern u1="Ç" u2="Ø" k="41"/><hkern u1="Ç" u2="Ö" k="41"/><hkern u1="Ç" u2="Õ" k="41"/><hkern u1="Ç" u2="Ô" k="41"/><hkern u1="Ç" u2="Ó" k="41"/><hkern u1="Ç" u2="Ò" k="41"/><hkern u1="Ç" u2="Ç" k="41"/><hkern u1="Ç" u2="Q" k="41"/><hkern u1="Ç" u2="O" k="41"/><hkern u1="Ç" u2="G" k="41"/><hkern u1="Ç" u2="C" k="41"/><hkern u1="È" u2="J" k="-123"/><hkern u1="É" u2="J" k="-123"/><hkern u1="Ê" u2="J" k="-123"/><hkern u1="Ë" u2="J" k="-123"/><hkern u1="Ð" u2="„" k="82"/><hkern u1="Ð" u2="‚" k="82"/><hkern u1="Ð" u2="Ÿ" k="20"/><hkern u1="Ð" u2="Ý" k="20"/><hkern u1="Ð" u2="Å" k="41"/><hkern u1="Ð" u2="Ä" k="41"/><hkern u1="Ð" u2="Ã" k="41"/><hkern u1="Ð" u2="Â" k="41"/><hkern u1="Ð" u2="Á" k="41"/><hkern u1="Ð" u2="À" k="41"/><hkern u1="Ð" u2="Z" k="20"/><hkern u1="Ð" u2="Y" k="20"/><hkern u1="Ð" u2="X" k="41"/><hkern u1="Ð" u2="W" k="20"/><hkern u1="Ð" u2="V" k="20"/><hkern u1="Ð" u2="T" k="61"/><hkern u1="Ð" u2="A" k="41"/><hkern u1="Ð" u2="." k="82"/><hkern u1="Ð" u2="," k="82"/><hkern u1="Ò" u2="„" k="82"/><hkern u1="Ò" u2="‚" k="82"/><hkern u1="Ò" u2="Ÿ" k="20"/><hkern u1="Ò" u2="Ý" k="20"/><hkern u1="Ò" u2="Å" k="41"/><hkern u1="Ò" u2="Ä" k="41"/><hkern u1="Ò" u2="Ã" k="41"/><hkern u1="Ò" u2="Â" k="41"/><hkern u1="Ò" u2="Á" k="41"/><hkern u1="Ò" u2="À" k="41"/><hkern u1="Ò" u2="Z" k="20"/><hkern u1="Ò" u2="Y" k="20"/><hkern u1="Ò" u2="X" k="41"/><hkern u1="Ò" u2="W" k="20"/><hkern u1="Ò" u2="V" k="20"/><hkern u1="Ò" u2="T" k="61"/><hkern u1="Ò" u2="A" k="41"/><hkern u1="Ò" u2="." k="82"/><hkern u1="Ò" u2="," k="82"/><hkern u1="Ó" u2="„" k="82"/><hkern u1="Ó" u2="‚" k="82"/><hkern u1="Ó" u2="Ÿ" k="20"/><hkern u1="Ó" u2="Ý" k="20"/><hkern u1="Ó" u2="Å" k="41"/><hkern u1="Ó" u2="Ä" k="41"/><hkern u1="Ó" u2="Ã" k="41"/><hkern u1="Ó" u2="Â" k="41"/><hkern u1="Ó" u2="Á" k="41"/><hkern u1="Ó" u2="À" k="41"/><hkern u1="Ó" u2="Z" k="20"/><hkern u1="Ó" u2="Y" k="20"/><hkern u1="Ó" u2="X" k="41"/><hkern u1="Ó" u2="W" k="20"/><hkern u1="Ó" u2="V" k="20"/><hkern u1="Ó" u2="T" k="61"/><hkern u1="Ó" u2="A" k="41"/><hkern u1="Ó" u2="." k="82"/><hkern u1="Ó" u2="," k="82"/><hkern u1="Ô" u2="„" k="82"/><hkern u1="Ô" u2="‚" k="82"/><hkern u1="Ô" u2="Ÿ" k="20"/><hkern u1="Ô" u2="Ý" k="20"/><hkern u1="Ô" u2="Å" k="41"/><hkern u1="Ô" u2="Ä" k="41"/><hkern u1="Ô" u2="Ã" k="41"/><hkern u1="Ô" u2="Â" k="41"/><hkern u1="Ô" u2="Á" k="41"/><hkern u1="Ô" u2="À" k="41"/><hkern u1="Ô" u2="Z" k="20"/><hkern u1="Ô" u2="Y" k="20"/><hkern u1="Ô" u2="X" k="41"/><hkern u1="Ô" u2="W" k="20"/><hkern u1="Ô" u2="V" k="20"/><hkern u1="Ô" u2="T" k="61"/><hkern u1="Ô" u2="A" k="41"/><hkern u1="Ô" u2="." k="82"/><hkern u1="Ô" u2="," k="82"/><hkern u1="Õ" u2="„" k="82"/><hkern u1="Õ" u2="‚" k="82"/><hkern u1="Õ" u2="Ÿ" k="20"/><hkern u1="Õ" u2="Ý" k="20"/><hkern u1="Õ" u2="Å" k="41"/><hkern u1="Õ" u2="Ä" k="41"/><hkern u1="Õ" u2="Ã" k="41"/><hkern u1="Õ" u2="Â" k="41"/><hkern u1="Õ" u2="Á" k="41"/><hkern u1="Õ" u2="À" k="41"/><hkern u1="Õ" u2="Z" k="20"/><hkern u1="Õ" u2="Y" k="20"/><hkern u1="Õ" u2="X" k="41"/><hkern u1="Õ" u2="W" k="20"/><hkern u1="Õ" u2="V" k="20"/><hkern u1="Õ" u2="T" k="61"/><hkern u1="Õ" u2="A" k="41"/><hkern u1="Õ" u2="." k="82"/><hkern u1="Õ" u2="," k="82"/><hkern u1="Ö" u2="„" k="82"/><hkern u1="Ö" u2="‚" k="82"/><hkern u1="Ö" u2="Ÿ" k="20"/><hkern u1="Ö" u2="Ý" k="20"/><hkern u1="Ö" u2="Å" k="41"/><hkern u1="Ö" u2="Ä" k="41"/><hkern u1="Ö" u2="Ã" k="41"/><hkern u1="Ö" u2="Â" k="41"/><hkern u1="Ö" u2="Á" k="41"/><hkern u1="Ö" u2="À" k="41"/><hkern u1="Ö" u2="Z" k="20"/><hkern u1="Ö" u2="Y" k="20"/><hkern u1="Ö" u2="X" k="41"/><hkern u1="Ö" u2="W" k="20"/><hkern u1="Ö" u2="V" k="20"/><hkern u1="Ö" u2="T" k="61"/><hkern u1="Ö" u2="A" k="41"/><hkern u1="Ö" u2="." k="82"/><hkern u1="Ö" u2="," k="82"/><hkern u1="Ø" u2="„" k="82"/><hkern u1="Ø" u2="‚" k="82"/><hkern u1="Ø" u2="Ÿ" k="20"/><hkern u1="Ø" u2="Ý" k="20"/><hkern u1="Ø" u2="Å" k="41"/><hkern u1="Ø" u2="Ä" k="41"/><hkern u1="Ø" u2="Ã" k="41"/><hkern u1="Ø" u2="Â" k="41"/><hkern u1="Ø" u2="Á" k="41"/><hkern u1="Ø" u2="À" k="41"/><hkern u1="Ø" u2="Z" k="20"/><hkern u1="Ø" u2="Y" k="20"/><hkern u1="Ø" u2="X" k="41"/><hkern u1="Ø" u2="W" k="20"/><hkern u1="Ø" u2="V" k="20"/><hkern u1="Ø" u2="T" k="61"/><hkern u1="Ø" u2="A" k="41"/><hkern u1="Ø" u2="." k="82"/><hkern u1="Ø" u2="," k="82"/><hkern u1="Ù" u2="„" k="41"/><hkern u1="Ù" u2="‚" k="41"/><hkern u1="Ù" u2="Å" k="20"/><hkern u1="Ù" u2="Ä" k="20"/><hkern u1="Ù" u2="Ã" k="20"/><hkern u1="Ù" u2="Â" k="20"/><hkern u1="Ù" u2="Á" k="20"/><hkern u1="Ù" u2="À" k="20"/><hkern u1="Ù" u2="A" k="20"/><hkern u1="Ù" u2="." k="41"/><hkern u1="Ù" u2="," k="41"/><hkern u1="Ú" u2="„" k="41"/><hkern u1="Ú" u2="‚" k="41"/><hkern u1="Ú" u2="Å" k="20"/><hkern u1="Ú" u2="Ä" k="20"/><hkern u1="Ú" u2="Ã" k="20"/><hkern u1="Ú" u2="Â" k="20"/><hkern u1="Ú" u2="Á" k="20"/><hkern u1="Ú" u2="À" k="20"/><hkern u1="Ú" u2="A" k="20"/><hkern u1="Ú" u2="." k="41"/><hkern u1="Ú" u2="," k="41"/><hkern u1="Û" u2="„" k="41"/><hkern u1="Û" u2="‚" k="41"/><hkern u1="Û" u2="Å" k="20"/><hkern u1="Û" u2="Ä" k="20"/><hkern u1="Û" u2="Ã" k="20"/><hkern u1="Û" u2="Â" k="20"/><hkern u1="Û" u2="Á" k="20"/><hkern u1="Û" u2="À" k="20"/><hkern u1="Û" u2="A" k="20"/><hkern u1="Û" u2="." k="41"/><hkern u1="Û" u2="," k="41"/><hkern u1="Ü" u2="„" k="41"/><hkern u1="Ü" u2="‚" k="41"/><hkern u1="Ü" u2="Å" k="20"/><hkern u1="Ü" u2="Ä" k="20"/><hkern u1="Ü" u2="Ã" k="20"/><hkern u1="Ü" u2="Â" k="20"/><hkern u1="Ü" u2="Á" k="20"/><hkern u1="Ü" u2="À" k="20"/><hkern u1="Ü" u2="A" k="20"/><hkern u1="Ü" u2="." k="41"/><hkern u1="Ü" u2="," k="41"/><hkern u1="Ý" u2="„" k="123"/><hkern u1="Ý" u2="‚" k="123"/><hkern u1="Ý" u2="œ" k="102"/><hkern u1="Ý" u2="Œ" k="41"/><hkern u1="Ý" u2="ü" k="61"/><hkern u1="Ý" u2="û" k="61"/><hkern u1="Ý" u2="ú" k="61"/><hkern u1="Ý" u2="ù" k="61"/><hkern u1="Ý" u2="ø" k="102"/><hkern u1="Ý" u2="ö" k="102"/><hkern u1="Ý" u2="õ" k="102"/><hkern u1="Ý" u2="ô" k="102"/><hkern u1="Ý" u2="ó" k="102"/><hkern u1="Ý" u2="ò" k="102"/><hkern u1="Ý" u2="ë" k="102"/><hkern u1="Ý" u2="ê" k="102"/><hkern u1="Ý" u2="é" k="102"/><hkern u1="Ý" u2="è" k="102"/><hkern u1="Ý" u2="ç" k="102"/><hkern u1="Ý" u2="æ" k="102"/><hkern u1="Ý" u2="å" k="102"/><hkern u1="Ý" u2="ä" k="102"/><hkern u1="Ý" u2="ã" k="102"/><hkern u1="Ý" u2="â" k="102"/><hkern u1="Ý" u2="á" k="102"/><hkern u1="Ý" u2="à" k="102"/><hkern u1="Ý" u2="Ø" k="41"/><hkern u1="Ý" u2="Ö" k="41"/><hkern u1="Ý" u2="Õ" k="41"/><hkern u1="Ý" u2="Ô" k="41"/><hkern u1="Ý" u2="Ó" k="41"/><hkern u1="Ý" u2="Ò" k="41"/><hkern u1="Ý" u2="Ç" k="41"/><hkern u1="Ý" u2="Å" k="123"/><hkern u1="Ý" u2="Ä" k="123"/><hkern u1="Ý" u2="Ã" k="123"/><hkern u1="Ý" u2="Â" k="123"/><hkern u1="Ý" u2="Á" k="123"/><hkern u1="Ý" u2="À" k="123"/><hkern u1="Ý" u2="z" k="41"/><hkern u1="Ý" u2="u" k="61"/><hkern u1="Ý" u2="s" k="82"/><hkern u1="Ý" u2="r" k="61"/><hkern u1="Ý" u2="q" k="102"/><hkern u1="Ý" u2="p" k="61"/><hkern u1="Ý" u2="o" k="102"/><hkern u1="Ý" u2="n" k="61"/><hkern u1="Ý" u2="m" k="61"/><hkern u1="Ý" u2="g" k="41"/><hkern u1="Ý" u2="e" k="102"/><hkern u1="Ý" u2="d" k="102"/><hkern u1="Ý" u2="c" k="102"/><hkern u1="Ý" u2="a" k="102"/><hkern u1="Ý" u2="Q" k="41"/><hkern u1="Ý" u2="O" k="41"/><hkern u1="Ý" u2="G" k="41"/><hkern u1="Ý" u2="C" k="41"/><hkern u1="Ý" u2="A" k="123"/><hkern u1="Ý" u2="?" k="-41"/><hkern u1="Ý" u2="." k="123"/><hkern u1="Ý" u2="," k="123"/><hkern u1="Þ" u2="„" k="266"/><hkern u1="Þ" u2="‚" k="266"/><hkern u1="Þ" u2="Å" k="102"/><hkern u1="Þ" u2="Ä" k="102"/><hkern u1="Þ" u2="Ã" k="102"/><hkern u1="Þ" u2="Â" k="102"/><hkern u1="Þ" u2="Á" k="102"/><hkern u1="Þ" u2="À" k="102"/><hkern u1="Þ" u2="Z" k="20"/><hkern u1="Þ" u2="X" k="41"/><hkern u1="Þ" u2="A" k="102"/><hkern u1="Þ" u2="." k="266"/><hkern u1="Þ" u2="," k="266"/><hkern u1="à" u2="”" k="20"/><hkern u1="à" u2="’" k="20"/><hkern u1="à" u2="'" k="20"/><hkern u1="à" u2="&quot;" k="20"/><hkern u1="á" u2="”" k="20"/><hkern u1="á" u2="’" k="20"/><hkern u1="á" u2="'" k="20"/><hkern u1="á" u2="&quot;" k="20"/><hkern u1="â" u2="”" k="20"/><hkern u1="â" u2="’" k="20"/><hkern u1="â" u2="'" k="20"/><hkern u1="â" u2="&quot;" k="20"/><hkern u1="ã" u2="”" k="20"/><hkern u1="ã" u2="’" k="20"/><hkern u1="ã" u2="'" k="20"/><hkern u1="ã" u2="&quot;" k="20"/><hkern u1="ä" u2="”" k="20"/><hkern u1="ä" u2="’" k="20"/><hkern u1="ä" u2="'" k="20"/><hkern u1="ä" u2="&quot;" k="20"/><hkern u1="å" u2="”" k="20"/><hkern u1="å" u2="’" k="20"/><hkern u1="å" u2="'" k="20"/><hkern u1="å" u2="&quot;" k="20"/><hkern u1="è" u2="”" k="20"/><hkern u1="è" u2="’" k="20"/><hkern u1="è" u2="ý" k="41"/><hkern u1="è" u2="z" k="20"/><hkern u1="è" u2="y" k="41"/><hkern u1="è" u2="x" k="41"/><hkern u1="è" u2="w" k="41"/><hkern u1="è" u2="v" k="41"/><hkern u1="è" u2="'" k="20"/><hkern u1="è" u2="&quot;" k="20"/><hkern u1="é" u2="”" k="20"/><hkern u1="é" u2="’" k="20"/><hkern u1="é" u2="ý" k="41"/><hkern u1="é" u2="z" k="20"/><hkern u1="é" u2="y" k="41"/><hkern u1="é" u2="x" k="41"/><hkern u1="é" u2="w" k="41"/><hkern u1="é" u2="v" k="41"/><hkern u1="é" u2="'" k="20"/><hkern u1="é" u2="&quot;" k="20"/><hkern u1="ê" u2="”" k="20"/><hkern u1="ê" u2="’" k="20"/><hkern u1="ê" u2="ý" k="41"/><hkern u1="ê" u2="z" k="20"/><hkern u1="ê" u2="y" k="41"/><hkern u1="ê" u2="x" k="41"/><hkern u1="ê" u2="w" k="41"/><hkern u1="ê" u2="v" k="41"/><hkern u1="ê" u2="'" k="20"/><hkern u1="ê" u2="&quot;" k="20"/><hkern u1="ë" u2="”" k="20"/><hkern u1="ë" u2="’" k="20"/><hkern u1="ë" u2="ý" k="41"/><hkern u1="ë" u2="z" k="20"/><hkern u1="ë" u2="y" k="41"/><hkern u1="ë" u2="x" k="41"/><hkern u1="ë" u2="w" k="41"/><hkern u1="ë" u2="v" k="41"/><hkern u1="ë" u2="'" k="20"/><hkern u1="ë" u2="&quot;" k="20"/><hkern u1="ð" u2="”" k="20"/><hkern u1="ð" u2="’" k="20"/><hkern u1="ð" u2="ý" k="41"/><hkern u1="ð" u2="z" k="20"/><hkern u1="ð" u2="y" k="41"/><hkern u1="ð" u2="x" k="41"/><hkern u1="ð" u2="w" k="41"/><hkern u1="ð" u2="v" k="41"/><hkern u1="ð" u2="'" k="20"/><hkern u1="ð" u2="&quot;" k="20"/><hkern u1="ò" u2="”" k="20"/><hkern u1="ò" u2="’" k="20"/><hkern u1="ò" u2="ý" k="41"/><hkern u1="ò" u2="z" k="20"/><hkern u1="ò" u2="y" k="41"/><hkern u1="ò" u2="x" k="41"/><hkern u1="ò" u2="w" k="41"/><hkern u1="ò" u2="v" k="41"/><hkern u1="ò" u2="'" k="20"/><hkern u1="ò" u2="&quot;" k="20"/><hkern u1="ó" u2="”" k="20"/><hkern u1="ó" u2="’" k="20"/><hkern u1="ó" u2="ý" k="41"/><hkern u1="ó" u2="z" k="20"/><hkern u1="ó" u2="y" k="41"/><hkern u1="ó" u2="x" k="41"/><hkern u1="ó" u2="w" k="41"/><hkern u1="ó" u2="v" k="41"/><hkern u1="ó" u2="'" k="20"/><hkern u1="ó" u2="&quot;" k="20"/><hkern u1="ô" u2="”" k="20"/><hkern u1="ô" u2="’" k="20"/><hkern u1="ô" u2="ý" k="41"/><hkern u1="ô" u2="z" k="20"/><hkern u1="ô" u2="y" k="41"/><hkern u1="ô" u2="x" k="41"/><hkern u1="ô" u2="w" k="41"/><hkern u1="ô" u2="v" k="41"/><hkern u1="ô" u2="'" k="20"/><hkern u1="ô" u2="&quot;" k="20"/><hkern u1="ö" u2="”" k="41"/><hkern u1="ö" u2="’" k="41"/><hkern u1="ö" u2="'" k="41"/><hkern u1="ö" u2="&quot;" k="41"/><hkern u1="ø" u2="”" k="20"/><hkern u1="ø" u2="’" k="20"/><hkern u1="ø" u2="ý" k="41"/><hkern u1="ø" u2="z" k="20"/><hkern u1="ø" u2="y" k="41"/><hkern u1="ø" u2="x" k="41"/><hkern u1="ø" u2="w" k="41"/><hkern u1="ø" u2="v" k="41"/><hkern u1="ø" u2="'" k="20"/><hkern u1="ø" u2="&quot;" k="20"/><hkern u1="ý" u2="„" k="82"/><hkern u1="ý" u2="”" k="-82"/><hkern u1="ý" u2="‚" k="82"/><hkern u1="ý" u2="’" k="-82"/><hkern u1="ý" u2="?" k="-41"/><hkern u1="ý" u2="." k="82"/><hkern u1="ý" u2="," k="82"/><hkern u1="ý" u2="'" k="-82"/><hkern u1="ý" u2="&quot;" k="-82"/><hkern u1="þ" u2="”" k="20"/><hkern u1="þ" u2="’" k="20"/><hkern u1="þ" u2="ý" k="41"/><hkern u1="þ" u2="z" k="20"/><hkern u1="þ" u2="y" k="41"/><hkern u1="þ" u2="x" k="41"/><hkern u1="þ" u2="w" k="41"/><hkern u1="þ" u2="v" k="41"/><hkern u1="þ" u2="'" k="20"/><hkern u1="þ" u2="&quot;" k="20"/><hkern u1="ÿ" u2="„" k="82"/><hkern u1="ÿ" u2="”" k="-82"/><hkern u1="ÿ" u2="‚" k="82"/><hkern u1="ÿ" u2="’" k="-82"/><hkern u1="ÿ" u2="?" k="-41"/><hkern u1="ÿ" u2="." k="82"/><hkern u1="ÿ" u2="," k="82"/><hkern u1="ÿ" u2="'" k="-82"/><hkern u1="ÿ" u2="&quot;" k="-82"/><hkern u1="Œ" u2="J" k="-123"/><hkern u1="Ÿ" u2="„" k="123"/><hkern u1="Ÿ" u2="‚" k="123"/><hkern u1="Ÿ" u2="œ" k="102"/><hkern u1="Ÿ" u2="Œ" k="41"/><hkern u1="Ÿ" u2="ü" k="61"/><hkern u1="Ÿ" u2="û" k="61"/><hkern u1="Ÿ" u2="ú" k="61"/><hkern u1="Ÿ" u2="ù" k="61"/><hkern u1="Ÿ" u2="ø" k="102"/><hkern u1="Ÿ" u2="ö" k="102"/><hkern u1="Ÿ" u2="õ" k="102"/><hkern u1="Ÿ" u2="ô" k="102"/><hkern u1="Ÿ" u2="ó" k="102"/><hkern u1="Ÿ" u2="ò" k="102"/><hkern u1="Ÿ" u2="ë" k="102"/><hkern u1="Ÿ" u2="ê" k="102"/><hkern u1="Ÿ" u2="é" k="102"/><hkern u1="Ÿ" u2="è" k="102"/><hkern u1="Ÿ" u2="ç" k="102"/><hkern u1="Ÿ" u2="æ" k="102"/><hkern u1="Ÿ" u2="å" k="102"/><hkern u1="Ÿ" u2="ä" k="102"/><hkern u1="Ÿ" u2="ã" k="102"/><hkern u1="Ÿ" u2="â" k="102"/><hkern u1="Ÿ" u2="á" k="102"/><hkern u1="Ÿ" u2="à" k="102"/><hkern u1="Ÿ" u2="Ø" k="41"/><hkern u1="Ÿ" u2="Ö" k="41"/><hkern u1="Ÿ" u2="Õ" k="41"/><hkern u1="Ÿ" u2="Ô" k="41"/><hkern u1="Ÿ" u2="Ó" k="41"/><hkern u1="Ÿ" u2="Ò" k="41"/><hkern u1="Ÿ" u2="Ç" k="41"/><hkern u1="Ÿ" u2="Å" k="123"/><hkern u1="Ÿ" u2="Ä" k="123"/><hkern u1="Ÿ" u2="Ã" k="123"/><hkern u1="Ÿ" u2="Â" k="123"/><hkern u1="Ÿ" u2="Á" k="123"/><hkern u1="Ÿ" u2="À" k="123"/><hkern u1="Ÿ" u2="z" k="41"/><hkern u1="Ÿ" u2="u" k="61"/><hkern u1="Ÿ" u2="s" k="82"/><hkern u1="Ÿ" u2="r" k="61"/><hkern u1="Ÿ" u2="q" k="102"/><hkern u1="Ÿ" u2="p" k="61"/><hkern u1="Ÿ" u2="o" k="102"/><hkern u1="Ÿ" u2="n" k="61"/><hkern u1="Ÿ" u2="m" k="61"/><hkern u1="Ÿ" u2="g" k="41"/><hkern u1="Ÿ" u2="e" k="102"/><hkern u1="Ÿ" u2="d" k="102"/><hkern u1="Ÿ" u2="c" k="102"/><hkern u1="Ÿ" u2="a" k="102"/><hkern u1="Ÿ" u2="Q" k="41"/><hkern u1="Ÿ" u2="O" k="41"/><hkern u1="Ÿ" u2="G" k="41"/><hkern u1="Ÿ" u2="C" k="41"/><hkern u1="Ÿ" u2="A" k="123"/><hkern u1="Ÿ" u2="?" k="-41"/><hkern u1="Ÿ" u2="." k="123"/><hkern u1="Ÿ" u2="," k="123"/><hkern u1="–" u2="T" k="82"/><hkern u1="—" u2="T" k="82"/><hkern u1="‘" u2="Ÿ" k="-20"/><hkern u1="‘" u2="œ" k="123"/><hkern u1="‘" u2="ü" k="61"/><hkern u1="‘" u2="û" k="61"/><hkern u1="‘" u2="ú" k="61"/><hkern u1="‘" u2="ù" k="61"/><hkern u1="‘" u2="ø" k="123"/><hkern u1="‘" u2="ö" k="123"/><hkern u1="‘" u2="õ" k="123"/><hkern u1="‘" u2="ô" k="123"/><hkern u1="‘" u2="ó" k="123"/><hkern u1="‘" u2="ò" k="123"/><hkern u1="‘" u2="ë" k="123"/><hkern u1="‘" u2="ê" k="123"/><hkern u1="‘" u2="é" k="123"/><hkern u1="‘" u2="è" k="123"/><hkern u1="‘" u2="ç" k="123"/><hkern u1="‘" u2="æ" k="82"/><hkern u1="‘" u2="å" k="82"/><hkern u1="‘" u2="ä" k="82"/><hkern u1="‘" u2="ã" k="82"/><hkern u1="‘" u2="â" k="82"/><hkern u1="‘" u2="á" k="82"/><hkern u1="‘" u2="à" k="123"/><hkern u1="‘" u2="Ý" k="-20"/><hkern u1="‘" u2="Å" k="143"/><hkern u1="‘" u2="Ä" k="143"/><hkern u1="‘" u2="Ã" k="143"/><hkern u1="‘" u2="Â" k="143"/><hkern u1="‘" u2="Á" k="143"/><hkern u1="‘" u2="À" k="143"/><hkern u1="‘" u2="u" k="61"/><hkern u1="‘" u2="s" k="61"/><hkern u1="‘" u2="r" k="61"/><hkern u1="‘" u2="q" k="123"/><hkern u1="‘" u2="p" k="61"/><hkern u1="‘" u2="o" k="123"/><hkern u1="‘" u2="n" k="61"/><hkern u1="‘" u2="m" k="61"/><hkern u1="‘" u2="g" k="61"/><hkern u1="‘" u2="e" k="123"/><hkern u1="‘" u2="d" k="123"/><hkern u1="‘" u2="c" k="123"/><hkern u1="‘" u2="a" k="82"/><hkern u1="‘" u2="Y" k="-20"/><hkern u1="‘" u2="W" k="-41"/><hkern u1="‘" u2="V" k="-41"/><hkern u1="‘" u2="T" k="-41"/><hkern u1="‘" u2="A" k="143"/><hkern u1="’" u2="Ÿ" k="-20"/><hkern u1="’" u2="œ" k="123"/><hkern u1="’" u2="ü" k="61"/><hkern u1="’" u2="û" k="61"/><hkern u1="’" u2="ú" k="61"/><hkern u1="’" u2="ù" k="61"/><hkern u1="’" u2="ø" k="123"/><hkern u1="’" u2="ö" k="123"/><hkern u1="’" u2="õ" k="123"/><hkern u1="’" u2="ô" k="123"/><hkern u1="’" u2="ó" k="123"/><hkern u1="’" u2="ò" k="123"/><hkern u1="’" u2="ë" k="123"/><hkern u1="’" u2="ê" k="123"/><hkern u1="’" u2="é" k="123"/><hkern u1="’" u2="è" k="123"/><hkern u1="’" u2="ç" k="123"/><hkern u1="’" u2="æ" k="82"/><hkern u1="’" u2="å" k="82"/><hkern u1="’" u2="ä" k="82"/><hkern u1="’" u2="ã" k="82"/><hkern u1="’" u2="â" k="82"/><hkern u1="’" u2="á" k="82"/><hkern u1="’" u2="à" k="123"/><hkern u1="’" u2="Ý" k="-20"/><hkern u1="’" u2="Å" k="143"/><hkern u1="’" u2="Ä" k="143"/><hkern u1="’" u2="Ã" k="143"/><hkern u1="’" u2="Â" k="143"/><hkern u1="’" u2="Á" k="143"/><hkern u1="’" u2="À" k="143"/><hkern u1="’" u2="u" k="61"/><hkern u1="’" u2="s" k="61"/><hkern u1="’" u2="r" k="61"/><hkern u1="’" u2="q" k="123"/><hkern u1="’" u2="p" k="61"/><hkern u1="’" u2="o" k="123"/><hkern u1="’" u2="n" k="61"/><hkern u1="’" u2="m" k="61"/><hkern u1="’" u2="g" k="61"/><hkern u1="’" u2="e" k="123"/><hkern u1="’" u2="d" k="123"/><hkern u1="’" u2="c" k="123"/><hkern u1="’" u2="a" k="82"/><hkern u1="’" u2="Y" k="-20"/><hkern u1="’" u2="W" k="-41"/><hkern u1="’" u2="V" k="-41"/><hkern u1="’" u2="T" k="-41"/><hkern u1="’" u2="A" k="143"/><hkern u1="‚" u2="Ÿ" k="123"/><hkern u1="‚" u2="Œ" k="102"/><hkern u1="‚" u2="Ý" k="123"/><hkern u1="‚" u2="Ü" k="41"/><hkern u1="‚" u2="Û" k="41"/><hkern u1="‚" u2="Ú" k="41"/><hkern u1="‚" u2="Ù" k="41"/><hkern u1="‚" u2="Ø" k="102"/><hkern u1="‚" u2="Ö" k="102"/><hkern u1="‚" u2="Õ" k="102"/><hkern u1="‚" u2="Ô" k="102"/><hkern u1="‚" u2="Ó" k="102"/><hkern u1="‚" u2="Ò" k="102"/><hkern u1="‚" u2="Ç" k="102"/><hkern u1="‚" u2="Y" k="123"/><hkern u1="‚" u2="W" k="123"/><hkern u1="‚" u2="V" k="123"/><hkern u1="‚" u2="U" k="41"/><hkern u1="‚" u2="T" k="143"/><hkern u1="‚" u2="Q" k="102"/><hkern u1="‚" u2="O" k="102"/><hkern u1="‚" u2="G" k="102"/><hkern u1="‚" u2="C" k="102"/><hkern u1="“" u2="Ÿ" k="-20"/><hkern u1="“" u2="œ" k="123"/><hkern u1="“" u2="ü" k="61"/><hkern u1="“" u2="û" k="61"/><hkern u1="“" u2="ú" k="61"/><hkern u1="“" u2="ù" k="61"/><hkern u1="“" u2="ø" k="123"/><hkern u1="“" u2="ö" k="123"/><hkern u1="“" u2="õ" k="123"/><hkern u1="“" u2="ô" k="123"/><hkern u1="“" u2="ó" k="123"/><hkern u1="“" u2="ò" k="123"/><hkern u1="“" u2="ë" k="123"/><hkern u1="“" u2="ê" k="123"/><hkern u1="“" u2="é" k="123"/><hkern u1="“" u2="è" k="123"/><hkern u1="“" u2="ç" k="123"/><hkern u1="“" u2="æ" k="82"/><hkern u1="“" u2="å" k="82"/><hkern u1="“" u2="ä" k="82"/><hkern u1="“" u2="ã" k="82"/><hkern u1="“" u2="â" k="82"/><hkern u1="“" u2="á" k="82"/><hkern u1="“" u2="à" k="123"/><hkern u1="“" u2="Ý" k="-20"/><hkern u1="“" u2="Å" k="143"/><hkern u1="“" u2="Ä" k="143"/><hkern u1="“" u2="Ã" k="143"/><hkern u1="“" u2="Â" k="143"/><hkern u1="“" u2="Á" k="143"/><hkern u1="“" u2="À" k="143"/><hkern u1="“" u2="u" k="61"/><hkern u1="“" u2="s" k="61"/><hkern u1="“" u2="r" k="61"/><hkern u1="“" u2="q" k="123"/><hkern u1="“" u2="p" k="61"/><hkern u1="“" u2="o" k="123"/><hkern u1="“" u2="n" k="61"/><hkern u1="“" u2="m" k="61"/><hkern u1="“" u2="g" k="61"/><hkern u1="“" u2="e" k="123"/><hkern u1="“" u2="d" k="123"/><hkern u1="“" u2="c" k="123"/><hkern u1="“" u2="a" k="82"/><hkern u1="“" u2="Y" k="-20"/><hkern u1="“" u2="W" k="-41"/><hkern u1="“" u2="V" k="-41"/><hkern u1="“" u2="T" k="-41"/><hkern u1="“" u2="A" k="143"/><hkern u1="„" u2="Ÿ" k="123"/><hkern u1="„" u2="Œ" k="102"/><hkern u1="„" u2="Ý" k="123"/><hkern u1="„" u2="Ü" k="41"/><hkern u1="„" u2="Û" k="41"/><hkern u1="„" u2="Ú" k="41"/><hkern u1="„" u2="Ù" k="41"/><hkern u1="„" u2="Ø" k="102"/><hkern u1="„" u2="Ö" k="102"/><hkern u1="„" u2="Õ" k="102"/><hkern u1="„" u2="Ô" k="102"/><hkern u1="„" u2="Ó" k="102"/><hkern u1="„" u2="Ò" k="102"/><hkern u1="„" u2="Ç" k="102"/><hkern u1="„" u2="Y" k="123"/><hkern u1="„" u2="W" k="123"/><hkern u1="„" u2="V" k="123"/><hkern u1="„" u2="U" k="41"/><hkern u1="„" u2="T" k="143"/><hkern u1="„" u2="Q" k="102"/><hkern u1="„" u2="O" k="102"/><hkern u1="„" u2="G" k="102"/><hkern u1="„" u2="C" k="102"/></font></defs></svg> \ No newline at end of file diff --git a/lib/web/fonts/opensans/bold/opensans-700.ttf b/lib/web/fonts/opensans/bold/opensans-700.ttf deleted file mode 100644 index 2109c958e3c5c..0000000000000 Binary files a/lib/web/fonts/opensans/bold/opensans-700.ttf and /dev/null differ diff --git a/lib/web/fonts/opensans/light/opensans-300.eot b/lib/web/fonts/opensans/light/opensans-300.eot deleted file mode 100644 index 14868406aa7d7..0000000000000 Binary files a/lib/web/fonts/opensans/light/opensans-300.eot and /dev/null differ diff --git a/lib/web/fonts/opensans/light/opensans-300.svg b/lib/web/fonts/opensans/light/opensans-300.svg deleted file mode 100644 index efddfe75be637..0000000000000 --- a/lib/web/fonts/opensans/light/opensans-300.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg"><defs><font horiz-adv-x="1169"><font-face units-per-em="2048" ascent="1638" descent="-410"/><glyph unicode="fi" horiz-adv-x="1077" d="M29 0zm557 1001H330V0h-99v1001H29v58l202 37v84q0 200 73.5 293.5T545 1567q90 0 180-27l-23-86q-80 25-159 25-116 0-164.5-68.5T330 1188v-101h256v-86zM895 0h-99v1087h99V0zM782 1389q0 96 63 96 31 0 48.5-25t17.5-71q0-45-17.5-71t-48.5-26q-63 0-63 97z"/><glyph unicode="fl" horiz-adv-x="1077" d="M29 0zm557 1001H330V0h-99v1001H29v58l202 37v84q0 200 73.5 293.5T545 1567q90 0 180-27l-23-86q-80 25-159 25-116 0-164.5-68.5T330 1188v-101h256v-86zM895 0h-99v1556h99V0z"/><glyph unicode="ffi" horiz-adv-x="1692" d="M29 0zm557 1001H330V0h-99v1001H29v58l202 37v84q0 200 73.5 293.5T545 1567q90 0 180-27l-23-86q-80 25-159 25-116 0-164.5-68.5T330 1188v-101h256v-86zm614 0H944V0h-99v1001H643v58l202 37v84q0 200 73.5 293.5T1159 1567q90 0 180-27l-23-86q-80 25-159 25-116 0-164.5-68.5T944 1188v-101h256v-86zM1510 0h-99v1087h99V0zm-113 1389q0 96 63 96 31 0 48.5-25t17.5-71q0-45-17.5-71t-48.5-26q-63 0-63 97z"/><glyph unicode="ffl" horiz-adv-x="1692" d="M29 0zm557 1001H330V0h-99v1001H29v58l202 37v84q0 200 73.5 293.5T545 1567q90 0 180-27l-23-86q-80 25-159 25-116 0-164.5-68.5T330 1188v-101h256v-86zm614 0H944V0h-99v1001H643v58l202 37v84q0 200 73.5 293.5T1159 1567q90 0 180-27l-23-86q-80 25-159 25-116 0-164.5-68.5T944 1188v-101h256v-86zM1510 0h-99v1556h99V0z"/><glyph horiz-adv-x="2048"/><glyph horiz-adv-x="2048"/><glyph horiz-adv-x="1044"/><glyph horiz-adv-x="532"/><glyph horiz-adv-x="532"/><glyph horiz-adv-x="532"/><glyph unicode="!" horiz-adv-x="492" d="M276 377h-61l-29 1085h119zM164 78q0 98 80 98 82 0 82-98t-82-98q-80 0-80 98z"/><glyph unicode="&quot;" horiz-adv-x="723" d="M260 1462l-33-528h-61l-33 528h127zm330 0l-33-528h-61l-33 528h127z"/><glyph unicode="#" horiz-adv-x="1323" d="M967 928l-76-398h303v-79H874L788 0h-90l88 451H426L340 0h-88l86 451H55v79h299l76 398H133v80h311l86 454h91l-89-454h365l88 454h86l-88-454h285v-80H967zM440 530h363l78 398H518z"/><glyph unicode="$" d="M991 440q0-133-99-217T618 117v-236h-81v232q-92 2-200.5 22.5T164 186v103q75-36 179.5-61T537 203v508q-145 44-215 88T220 903t-32 146q0 124 94.5 208.5T537 1362v192h81v-190q197-9 351-72l-33-90q-141 62-318 72V788q213-66 293-144t80-204zm-110 4q0 85-63 140.5T618 680V209q122 13 192.5 75T881 444zm-584 605q0-86 57-141t183-93v453q-119-16-179.5-76T297 1049z"/><glyph unicode="%" horiz-adv-x="1653" d="M211 1026q0-186 45-279.5T397 653q193 0 193 373 0 184-49.5 276.5T397 1395q-96 0-141-92.5T211 1026zm477 0q0-226-75-343.5T397 565q-133 0-208.5 120.5T113 1026q0 223 72 340t212 117q139 0 215-120.5t76-336.5zm375-588q0-185 45-277.5T1249 68q193 0 193 370 0 369-193 369-96 0-141-91.5T1063 438zm477 0q0-226-74-343.5T1251-23q-136 0-211 121.5T965 438q0 225 73.5 341T1251 895q137 0 213-120t76-337zm-260 1024L469 0h-96l811 1462h96z"/><glyph unicode="&" horiz-adv-x="1460" d="M123 371q0 138 73.5 235T471 811l-75 82q-66 71-98 139t-32 142q0 143 95.5 227t256.5 84q155 0 245.5-81t90.5-224q0-105-70-192.5T631 793l452-457q61 72 104 157t75 201h96q-63-246-209-426L1415 0h-135l-193 197q-92-90-164-131.5T765.5 2 571-20Q362-20 242.5 83T123 371zM578 70q128 0 234.5 43.5T1022 260L539 745q-136-72-196.5-122.5t-88-109.5T227 375q0-143 93-224t258-81zM373 1176q0-79 40-146t152-174q159 85 221 159t62 169q0 94-62 152.5T618 1395q-114 0-179.5-58T373 1176z"/><glyph unicode="'" horiz-adv-x="393" d="M260 1462l-33-528h-61l-33 528h127z"/><glyph unicode="(" horiz-adv-x="557" d="M82 561q0 265 77.5 496T383 1462h113q-148-182-227-412.5T190 563q0-483 304-887H383Q236-154 159 73T82 561z"/><glyph unicode=")" horiz-adv-x="557" d="M475 561q0-263-77.5-490T174-324H63Q367 80 367 563q0 257-79 487.5T61 1462h113q147-175 224-406.5T475 561z"/><glyph unicode="*" horiz-adv-x="1128" d="M631 1556l-37-405 405 104 21-131-395-39 247-340-124-71-191 379-180-379-125 71 242 340-390 39 19 131 401-104-39 405h146z"/><glyph unicode="+" d="M625 764h434v-82H625V250h-82v432H111v82h432v434h82V764z"/><glyph unicode="," horiz-adv-x="440" d="M295 238l12-21Q232-48 133-264H68q77 275 110 502h117z"/><glyph unicode="-" horiz-adv-x="659" d="M92 512v82h475v-82H92z"/><glyph unicode="." horiz-adv-x="487" d="M162 78q0 98 80 98 82 0 82-98t-82-98q-80 0-80 98z"/><glyph unicode="/" horiz-adv-x="698" d="M674 1462L129 0H25l544 1462h105z"/><glyph unicode="0" d="M1055 735q0-385-117.5-570T582-20q-229 0-348 190.5T115 735q0 382 115.5 566T582 1485q231 0 352-190.5T1055 735zm-832 0q0-340 89-502.5T582 70q189 0 275.5 168T944 735q0 324-86.5 492T582 1395t-274-168-85-492z"/><glyph unicode="1" d="M682 0h-98v1065q0 145 12 301-15-15-31-29t-309-243l-57 71 397 297h86V0z"/><glyph unicode="2" d="M1028 0H113v88l389 406q164 170 230 260t97 172 31 172q0 131-86 213t-223 82q-183 0-350-133l-54 69q183 154 406 154 191 0 300.5-102T963 1100q0-145-73.5-280.5T621 485L246 100v-4h782V0z"/><glyph unicode="3" d="M979 1118q0-136-85.5-229T664 770v-6q176-22 268-112t92-242q0-205-139.5-317.5T483-20Q260-20 94 63v99q84-44 188.5-69T479 68q221 0 332 89.5T922 410q0 145-113.5 223T475 711H317v96h160q182 0 288.5 86.5T872 1128q0 122-86.5 195.5T559 1397q-109 0-199-30.5T158 1262l-49 67q85 71 205 112.5t243 41.5q202 0 312-95.5T979 1118z"/><glyph unicode="4" d="M1141 373H889V0h-94v373H43v67l725 1030h121V459h252v-86zm-346 86v418q0 302 14 507h-8q-20-37-123-188L162 459h633z"/><glyph unicode="5" d="M537 879q234 0 368.5-113T1040 455q0-225-140-350T514-20Q405-20 307 1.5T143 63v103q108-55 192-76.5T514 68q192 0 308 101.5T938 444q0 163-113 256t-307 93q-130 0-272-39l-60 39 58 669h704v-96H338l-45-516q156 29 244 29z"/><glyph unicode="6" d="M131 623q0 285 77.5 479.5t220 288.5 343.5 94q94 0 172-23v-88q-73 27-176 27-247 0-384.5-178T229 705h13q76 98 174 148t207 50q205 0 320.5-117T1059 463q0-224-121.5-353.5T610-20q-222 0-350.5 169.5T131 623zM610 68q164 0 255 103t91 294q0 168-90 262t-245 94q-102 0-189.5-45T292 656.5 240 504q0-111 49.5-213.5t134-162.5T610 68z"/><glyph unicode="7" d="M334 0l602 1366H109v96h946v-73L451 0H334z"/><glyph unicode="8" d="M582 1487q186 0 299.5-95T995 1135q0-112-70.5-198T696 778q192-79 270-173t78-228q0-181-126.5-289T578-20Q357-20 239 81T121 375q0 131 83 230t257 169q-161 76-227 160.5T168 1137q0 105 53 184.5T369.5 1444t212.5 43zM223 360q0-138 93.5-214T578 70q164 0 264 80.5T942 369q0 124-78.5 201.5T561 733q-184-71-261-157t-77-216zm357 1037q-141 0-226.5-69.5T268 1137q0-70 31.5-123.5t91-97T590 815q163 63 234 139t71 183q0 120-84.5 190T580 1397z"/><glyph unicode="9" d="M1036 842q0-288-75.5-482t-220-287T391-20Q287-20 199 6v86q43-14 103.5-21.5T395 63q247 0 387 178.5T938 762h-12q-73-96-174-147.5T541 563q-203 0-316.5 112T111 993q0 220 124.5 356T559 1485q144 0 252-75.5T977.5 1188t58.5-346zm-477 555q-158 0-252-106.5T213 999q0-174 87-264t249-90q101 0 188.5 45t139 119.5T928 961q0 117-46.5 219t-130 159.5T559 1397z"/><glyph unicode=":" horiz-adv-x="487" d="M162 78q0 98 80 98 82 0 82-98t-82-98q-80 0-80 98zm0 893q0 98 80 98 82 0 82-98 0-53-23.5-76T242 872q-34 0-57 23t-23 76z"/><glyph unicode=";" horiz-adv-x="487" d="M303 238l12-21Q240-48 141-264H76q29 97 62 245.5T186 238h117zM162 971q0 98 80 98 82 0 82-98 0-53-23.5-76T242 872q-34 0-57 23t-23 76z"/><glyph unicode="<" d="M1059 266L111 682v61l948 474v-95L236 717l823-355v-96z"/><glyph unicode="=" d="M111 885v82h948v-82H111zm0-408v82h948v-82H111z"/><glyph unicode=">" d="M111 362l823 355-823 405v95l948-474v-61L111 266v96z"/><glyph unicode="?" horiz-adv-x="862" d="M293 377v37q0 123 37.5 201T469 782l91 79q72 61 103 121t31 138q0 127-83.5 202T391 1397q-79 0-148-17.5T94 1323l-37 80q110 48 184.5 64t153.5 16q183 0 288-98.5T788 1114q0-68-18-119t-50.5-94.5-78.5-84T539 729q-64-54-98.5-98.5t-50-93.5T375 391v-14h-82zM260 78q0 98 80 98 82 0 82-98t-82-98q-80 0-80 98z"/><glyph unicode="@" horiz-adv-x="1815" d="M1702 725q0-228-90.5-366T1366 221q-89 0-144.5 54T1157 422h-4q-43-100-124-150.5T840 221q-148 0-229 96.5T530 588q0 202 120.5 330.5T965 1047q138 0 286-41l-22-464v-30q0-104 35-156.5t116-52.5q103 0 168.5 116.5T1614 723q0 194-79 340t-225.5 224.5T975 1366q-230 0-405.5-99.5T299.5 985 205 567q0-322 167-497.5T846-106q93 0 188.5 18T1266-18v-99q-203-80-414-80-349 0-544 200.5T113 561q0 256 108.5 460.5t307 317.5T977 1452q215 0 380.5-89t255-254.5T1702 725zM633 590q0-143 55-215t174-72q255 0 273 346l16 291q-79 27-193 27-149 0-237-102.5T633 590z"/><glyph unicode="A" horiz-adv-x="1229" d="M911 516H317L113 0H0l588 1468h65L1229 0h-115zm-557 92h523l-199 527q-25 62-60 172-27-96-59-174z"/><glyph unicode="B" horiz-adv-x="1284" d="M207 1462h401q271 0 398-92t127-278q0-127-77.5-211.5T829 772v-6q175-26 257.5-110.5T1169 420q0-202-134-311T655 0H207v1462zm102-651h322q206 0 299.5 68.5T1024 1094t-105.5 212-314.5 66H309V811zm0-90V90h344q406 0 406 330 0 301-428 301H309z"/><glyph unicode="C" horiz-adv-x="1272" d="M831 1391q-275 0-433-176T240 733q0-313 149-486T815 74q184 0 338 47V31q-145-51-362-51-308 0-485 199T129 735q0 223 84.5 393t243 262.5T825 1483q214 0 383-80l-41-92q-160 80-336 80z"/><glyph unicode="D" horiz-adv-x="1446" d="M1317 745q0-368-193-556.5T557 0H207v1462h395q350 0 532.5-183T1317 745zm-111-4q0 314-159.5 472.5T578 1372H309V90h242q655 0 655 651z"/><glyph unicode="E" horiz-adv-x="1130" d="M1006 0H207v1462h799v-94H309V815h658v-94H309V94h697V0z"/><glyph unicode="F" horiz-adv-x="1028" d="M309 0H207v1462h801v-94H309V748h660v-95H309V0z"/><glyph unicode="G" horiz-adv-x="1481" d="M782 737h539V70q-212-90-477-90-346 0-530.5 195.5T129 729q0 223 91.5 395.5t262 266.5 391.5 94q239 0 429-88l-41-92q-190 88-394 88-289 0-458.5-178.5T240 733q0-330 161-496.5T874 70q202 0 343 57v514H782v96z"/><glyph unicode="H" horiz-adv-x="1473" d="M1266 0h-103v719H309V0H207v1462h102V813h854v649h103V0z"/><glyph unicode="I" horiz-adv-x="516" d="M207 0v1462h102V0H207z"/><glyph unicode="J" horiz-adv-x="506" d="M-33-369q-92 0-151 27v88q78-20 149-20 242 0 242 264v1472h102V0q0-369-342-369z"/><glyph unicode="K" horiz-adv-x="1190" d="M1190 0h-125L504 772 309 600V0H207v1462h102V702l162 162 573 598h130L575 844z"/><glyph unicode="L" horiz-adv-x="1051" d="M207 0v1462h102V96h697V0H207z"/><glyph unicode="M" horiz-adv-x="1767" d="M850 0L305 1350h-8q8-124 8-254V0h-98v1462h158L883 176h6l518 1286h154V0h-103v1108q0 116 12 240h-8L915 0h-65z"/><glyph unicode="N" horiz-adv-x="1477" d="M1270 0h-103L301 1298h-8q12-232 12-350V0h-98v1462h102l865-1296h6q-9 180-9 342v954h99V0z"/><glyph unicode="O" horiz-adv-x="1565" d="M1436 733q0-348-174-550.5T782-20q-305 0-479 202.5T129 735q0 349 175.5 549.5T784 1485q306 0 479-201.5T1436 733zm-1196 0q0-314 140-485.5T782 76q264 0 403.5 170T1325 733q0 316-139.5 484.5T784 1386q-261 0-402.5-170T240 733z"/><glyph unicode="P" horiz-adv-x="1198" d="M1087 1042q0-212-144-325T535 604H309V0H207v1462h358q522 0 522-420zM309 692h201q247 0 357 81.5T977 1038q0 169-104 250.5T551 1370H309V692z"/><glyph unicode="Q" horiz-adv-x="1565" d="M1436 733q0-294-126-486.5T961 0l333-348h-166L846-18l-33-2h-31q-305 0-479 202.5T129 735q0 349 175.5 549.5T784 1485q306 0 479-201.5T1436 733zm-1196 0q0-314 140-485.5T782 76q264 0 403.5 170T1325 733q0 316-139.5 484.5T784 1386q-261 0-402.5-170T240 733z"/><glyph unicode="R" horiz-adv-x="1217" d="M309 637V0H207v1462h348q272 0 402-100.5t130-302.5q0-147-77.5-248T774 666L1171 0h-122L672 637H309zm0 88h279q185 0 287 82.5T977 1051q0 167-100 243t-326 76H309V725z"/><glyph unicode="S" horiz-adv-x="1116" d="M1014 377q0-183-134.5-290T522-20q-268 0-411 59v102q158-67 403-67 180 0 285.5 82.5T905 373q0 83-35 137.5T756 610t-232 97q-224 77-309.5 166.5T129 1112q0 164 128.5 267.5T588 1483q206 0 387-78l-37-88q-182 76-348 76-162 0-258-75t-96-204q0-81 29.5-133t96.5-93.5T592 788q171-59 257-114.5t125.5-126T1014 377z"/><glyph unicode="T" horiz-adv-x="1073" d="M588 0H485v1366H10v96h1053v-96H588V0z"/><glyph unicode="U" horiz-adv-x="1473" d="M1282 1462V516q0-252-146-394T729-20q-254 0-396.5 142.5T190 520v942h103V516q0-211 117-328.5T741 70q209 0 324 115.5T1180 506v956h102z"/><glyph unicode="V" horiz-adv-x="1182" d="M1071 1462h111L635 0h-90L0 1462h109l368-995q84-225 113-338 20 75 79 233z"/><glyph unicode="W" horiz-adv-x="1827" d="M1372 0h-84L967 1128q-40 139-60 228-16-87-45.5-200T539 0h-86L51 1462h107l256-942q15-57 28-105.5t23.5-91 19-82T500 162q24 136 102 413l250 887h113l293-1018q51-176 73-284 13 72 33.5 153T1673 1462h103z"/><glyph unicode="X" horiz-adv-x="1102" d="M1102 0H985L553 682 113 0H0l492 762-447 700h115l395-626 401 626h109L612 764z"/><glyph unicode="Y" horiz-adv-x="1081" d="M543 662l428 800h110L594 565V0H489v557L0 1462h117z"/><glyph unicode="Z" horiz-adv-x="1180" d="M1098 0H82v76l856 1290H121v96h954v-76L217 96h881V0z"/><glyph unicode="[" horiz-adv-x="653" d="M602-324H174v1786h428v-94H272V-229h330v-95z"/><glyph unicode="\" horiz-adv-x="698" d="M127 1462L674 0H571L25 1462h102z"/><glyph unicode="]" horiz-adv-x="653" d="M51-229h330v1597H51v94h428V-324H51v95z"/><glyph unicode="^" d="M88 561l465 912h68l460-912H981l-395 791-398-791H88z"/><glyph unicode="_" horiz-adv-x="842" d="M846-266H-4v82h850v-82z"/><glyph unicode="`" horiz-adv-x="1182" d="M776 1241h-69q-96 79-188.5 171.5T393 1552v17h142q26-48 98.5-142T776 1257v-16z"/><glyph unicode="a" horiz-adv-x="1085" d="M842 0l-25 172h-8Q727 67 640.5 23.5T436-20q-160 0-249 82T98 289q0 159 132.5 247T614 629l207 6v72q0 155-63 234t-203 79q-151 0-313-84l-37 86q179 84 354 84 179 0 267.5-93T915 723V0h-73zM442 70q174 0 274.5 99.5T817 446v107l-190-8q-229-11-326.5-71.5T203 285q0-102 62.5-158.5T442 70z"/><glyph unicode="b" horiz-adv-x="1219" d="M641 1108q228 0 343.5-143.5T1100 545q0-271-121.5-418T637-20q-116 0-209 48T281 164h-9L244 0h-62v1556h99v-391q0-88-4-162l-3-85h7q62 98 149.5 144t210.5 46zm-2-90q-192 0-275-110t-83-363v-17q0-246 86.5-353T637 68q178 0 268 124.5T995 547q0 471-356 471z"/><glyph unicode="c" horiz-adv-x="973" d="M616-20q-233 0-365 147T119 537q0 270 137 420.5T631 1108q141 0 270-49l-27-88q-141 47-245 47-200 0-303-123.5T223 539q0-220 103-344.5T614 70q148 0 275 53V31Q785-20 616-20z"/><glyph unicode="d" horiz-adv-x="1219" d="M580 1108q118 0 204-43t154-147h6q-6 126-6 247v391h98V0h-65l-25 166h-8Q814-20 582-20q-225 0-344 140T119 528q0 282 118 431t343 149zm0-90q-178 0-267.5-125T223 530q0-462 359-462 184 0 270 107t86 353v17q0 252-84.5 362.5T580 1018z"/><glyph unicode="e" horiz-adv-x="1124" d="M621-20q-237 0-369.5 146T119 535q0 260 128 416.5T592 1108q192 0 303-134t111-364v-80H223q2-224 104.5-342T621 70q93 0 163.5 13T963 139V49Q871 9 793-5.5T621-20zm-29 1040q-157 0-252-103.5T229 618h672q0 189-82 295.5T592 1020z"/><glyph unicode="f" horiz-adv-x="614" d="M586 1001H330V0h-99v1001H29v58l202 37v84q0 200 73.5 293.5T545 1567q90 0 180-27l-23-86q-80 25-159 25-116 0-164.5-68.5T330 1188v-101h256v-86z"/><glyph unicode="g" horiz-adv-x="1071" d="M1030 1087v-69l-225-14q90-112 90-246 0-157-104.5-254.5T510 406q-74 0-104 6-59-31-90-73t-31-89q0-52 39.5-76T457 150h190q177 0 271-71.5t94-211.5q0-172-139.5-265.5T475-492q-205 0-317.5 79T45-193Q45-81 114.5-7T303 94q-49 21-78.5 59.5T195 242q0 109 139 192-95 39-148 122.5T133 748q0 163 103.5 261.5T516 1108q107 0 166-21h348zM150-184q0-224 333-224 428 0 428 273 0 98-67 142T627 51H449q-299 0-299-235zm83 932q0-126 76.5-195.5T514 483q136 0 208.5 69T795 752q0 139-74.5 208.5T512 1030q-130 0-204.5-74.5T233 748z"/><glyph unicode="h" horiz-adv-x="1208" d="M940 0v705q0 164-69 238.5T657 1018q-195 0-285.5-98.5T281 600V0h-99v1556h99v-495l-5-139h7q61 98 154 142t231 44q370 0 370-397V0h-98z"/><glyph unicode="i" horiz-adv-x="463" d="M281 0h-99v1087h99V0zM168 1389q0 96 63 96 31 0 48.5-25t17.5-71q0-45-17.5-71t-48.5-26q-63 0-63 97z"/><glyph unicode="j" horiz-adv-x="463" d="M37-492q-80 0-135 25v86q69-20 129-20 151 0 151 176v1312h99V-211q0-135-63.5-208T37-492zm131 1881q0 96 63 96 31 0 48.5-25t17.5-71q0-45-17.5-71t-48.5-26q-63 0-63 97z"/><glyph unicode="k" horiz-adv-x="991" d="M279 477l555 610h120L526 623 991 0H872L459 549 281 387V0h-99v1556h99V776l-7-299h5z"/><glyph unicode="l" horiz-adv-x="463" d="M281 0h-99v1556h99V0z"/><glyph unicode="m" horiz-adv-x="1808" d="M1540 0v713q0 159-62 232t-190 73q-167 0-247-92t-80-289V0H860v743q0 275-252 275-171 0-249-99.5T281 600V0h-99v1087h82l21-149h6q45 81 128 125.5t183 44.5q257 0 330-193h4q53 93 142.5 143t203.5 50q178 0 267-95t89-302V0h-98z"/><glyph unicode="n" horiz-adv-x="1208" d="M940 0v705q0 164-69 238.5T657 1018q-195 0-285.5-98.5T281 600V0h-99v1087h84l19-149h6q106 170 377 170 370 0 370-397V0h-98z"/><glyph unicode="o" horiz-adv-x="1200" d="M1081 545q0-266-129-415.5T596-20q-143 0-252 69T177 247t-58 298q0 266 129 414.5T602 1108q224 0 351.5-150.5T1081 545zm-858 0q0-224 98.5-349.5T600 70t278.5 125.5T977 545q0 225-99.5 349T598 1018 320.5 894.5 223 545z"/><glyph unicode="p" horiz-adv-x="1219" d="M647-20q-251 0-366 188h-7l3-84q4-74 4-162v-414h-99v1579h84l19-155h6q112 176 358 176 220 0 335.5-144.5T1100 543q0-268-121.5-415.5T647-20zm-2 88q167 0 258.5 124T995 539q0 479-346 479-190 0-279-104.5T281 573v-32q0-255 85.5-364T645 68z"/><glyph unicode="q" horiz-adv-x="1219" d="M569-20q-214 0-332 142T119 532q0 275 118 425.5T575 1108q236 0 353-174h6l18 153h84V-492h-98v414q0 122 6 248h-6Q820-20 569-20zm2 88q198 0 282.5 109T938 543v12q0 245-85 354t-271 109q-176 0-267.5-124T223 530q0-229 89.5-345.5T571 68z"/><glyph unicode="r" horiz-adv-x="797" d="M610 1108q69 0 148-14l-19-95q-68 17-141 17-139 0-228-118t-89-298V0h-99v1087h84l10-196h7q67 120 143 168.5t184 48.5z"/><glyph unicode="s" horiz-adv-x="954" d="M856 283q0-146-111-224.5T430-20Q212-20 84 47v107q164-82 346-82 161 0 244.5 53.5T758 268q0 82-66.5 138T473 516q-163 59-229 101.5t-99.5 96T111 844q0 122 102.5 193t286.5 71q176 0 334-66l-37-90q-160 66-297 66-133 0-211-44t-78-122q0-85 60.5-136T508 602q147-53 214-95.5T822.5 410 856 283z"/><glyph unicode="t" horiz-adv-x="686" d="M469 68q94 0 164 16V4q-72-24-166-24-144 0-212.5 77T186 299v702H25v58l161 45 50 246h51v-263h319v-86H287V313q0-125 44-185t138-60z"/><glyph unicode="u" horiz-adv-x="1208" d="M268 1087V383q0-164 69-238.5T551 70q194 0 285.5 98T928 487v600h98V0h-84l-18 150h-6Q812-20 541-20q-371 0-371 397v710h98z"/><glyph unicode="v" horiz-adv-x="940" d="M420 0L0 1087h102l281-739q56-142 84-248h6q41 136 84 250l281 737h102L520 0H420z"/><glyph unicode="w" horiz-adv-x="1481" d="M1051 0L813 727q-23 74-59 217h-6l-21-74-45-145L440 0h-98L31 1087h106l174-630q61-234 80-344h6q59 234 86 311l224 663h90l213-661q72-235 88-311h6q8 65 80 348l166 624h100L1155 0h-104z"/><glyph unicode="x" horiz-adv-x="1020" d="M449 559L70 1087h114l324-458 321 458h109L565 559 965 0H850L508 485 164 0H55z"/><glyph unicode="y" horiz-adv-x="940" d="M0 1087h102l230-610Q437 196 465 98h6q42 129 137 385l230 604h102L453-176q-59-154-99-208t-93.5-81T131-492q-57 0-127 21v86q58-16 125-16 51 0 90 24t70.5 74.5 73 160T416 0z"/><glyph unicode="z" horiz-adv-x="944" d="M858 0H82v63l645 936H129v88h727v-63L207 88h651V0z"/><glyph unicode="{" horiz-adv-x="723" d="M389-27q0-102 59.5-152.5T651-233v-91q-195 0-277.5 75T291-18v337q0 205-230 209v80q122 2 176 51t54 148v350q0 299 360 305v-90q-138-5-200-58t-62-157V852q0-130-44-194t-142-85v-8q97-20 141.5-83.5T389 295V-27z"/><glyph unicode="|" horiz-adv-x="1108" d="M508 1561h92V-506h-92v2067z"/><glyph unicode="}" horiz-adv-x="723" d="M334 295q0 123 44.5 186.5T520 565v8q-97 20-141.5 84T334 852v305q0 103-61.5 156.5T72 1372v90q174 0 267-77.5t93-227.5V807q0-100 54.5-148.5T662 608v-80q-230-4-230-209V-18q0-155-82.5-230.5T72-324v91q141 2 201.5 52.5T334-27v322z"/><glyph unicode="~" d="M334 745q-49 0-108-30.5T111 625v94q108 110 233 110 61 0 115-13.5T614 758q126-58 220-58 56 0 109.5 30.5T1059 825v-96q-48-49-104.5-81T825 616q-116 0-270 72-124 57-221 57z"/><glyph unicode="¡" horiz-adv-x="492" d="M215 711h61l29-1086H186zm-49 299q0 98 80 98 82 0 82-98 0-53-23.5-76T246 911q-34 0-57 23t-23 76z"/><glyph unicode="¢" d="M602 190q-186 30-288.5 175T211 745q0 232 102.5 381.5T602 1309v174h82v-166h14q131 0 275-55l-31-84q-134 51-237 51-187 0-288.5-122.5T315 748q0-225 100.5-349.5T696 274q131 0 267 58v-92q-110-56-267-56h-12V-20h-82v210z"/><glyph unicode="£" d="M412 676V420q0-116-35-196T264 96h809V0H78v84q110 21 171.5 110T311 418v258H100v82h211v297q0 204 98 315t281 111q175 0 330-68l-35-86q-157 66-295 66-141 0-209.5-81T412 1059V758h411v-82H412z"/><glyph unicode="¤" d="M991 723q0-151-90-256l139-141-59-60-137 142q-110-93-260-93-153 0-260 93L186 266l-59 60 139 141q-90 106-90 256 0 147 90 258l-139 141 59 60 138-142q103 93 260 93 155 0 260-93l137 142 59-60-139-141q90-111 90-258zM584 395q134 0 228.5 95.5T907 723q0 136-95 233t-228 97q-134 0-229-97t-95-233 94.5-232T584 395z"/><glyph unicode="¥" d="M586 666l428 796h110L692 674h283v-82H637V387h338v-82H637V0H532v305H195v82h337v205H195v82h278L43 1462h117z"/><glyph unicode="¦" horiz-adv-x="1108" d="M508 1561h92V797h-92v764zm0-1303h92v-764h-92v764z"/><glyph unicode="§" horiz-adv-x="1057" d="M145 813q0 83 50.5 152.5T334 1073q-86 47-125 102t-39 136q0 117 101.5 183.5T547 1561q175 0 336-64l-35-80q-91 34-158.5 47T545 1477q-134 0-205.5-44.5T268 1313q0-54 25.5-88.5T379 1159t188-74q192-64 264-132.5T903 782q0-173-186-274 86-42 129-96t43-136q0-135-113-207.5T465-4q-92 0-171 15T129 63v95q182-78 332-78 162 0 247 49.5T793 270q0 55-25 87.5T679.5 423 489 502q-200 73-272 141.5T145 813zm101 12q0-65 31.5-104T383 646t250-99q82 41 126 98t44 121q0 62-32 102t-108.5 77-236.5 87q-81-23-130.5-79T246 825z"/><glyph unicode="¨" horiz-adv-x="1182" d="M336 1389q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="©" horiz-adv-x="1704" d="M897 1092q-142 0-222.5-94.5T594 733q0-186 74.5-275T889 369q84 0 198 43v-88q-102-45-208-45-187 0-288.5 115T489 725q0 208 111 332.5T897 1182q119 0 227-52l-37-83q-98 45-190 45zM100 731q0 200 100 375t275 276 377 101q200 0 375-100t276-275 101-377q0-197-97-370T1235 84 852-20Q645-20 470 83.5T197.5 360 100 731zm93 0q0-178 88.5-329.5T522 161t330-89 329.5 88.5T1422 401t89 330q0 174-85.5 325t-239 243-334.5 92q-176 0-328.5-88.5T282 1060t-89-329z"/><glyph unicode="ª" horiz-adv-x="686" d="M512 813l-25 72q-84-84-202-84-95 0-151 49T78 989q0 100 80 151.5t241 59.5l95 4v43q0 77-38 114.5T350 1399q-87 0-196-49l-33 73q117 56 231 56 228 0 228-215V813h-68zM168 993q0-54 35-85t96-31q90 0 142.5 50t52.5 142v64l-88-5q-116-6-177-36.5T168 993z"/><glyph unicode="«" horiz-adv-x="885" d="M82 543l309 393 62-43-254-363 254-362-62-43L82 516v27zm360 0l310 393 61-43-254-363 254-362-61-43-310 391v27z"/><glyph unicode="¬" d="M1038 764V270h-82v412H111v82h927z"/><glyph unicode="­" horiz-adv-x="659" d="M92 512zm0 0v82h475v-82H92z"/><glyph unicode="®" horiz-adv-x="1704" d="M709 731h112q91 0 143 46.5t52 135.5q0 172-197 172H709V731zm411 187q0-79-38.5-139.5T971 684l237-393h-121L877 651H709V291H608v880h211q143 0 222-62t79-191zM100 731q0 200 100 375t275 276 377 101q200 0 375-100t276-275 101-377q0-197-97-370T1235 84 852-20Q645-20 470 83.5T197.5 360 100 731zm93 0q0-178 88.5-329.5T522 161t330-89 329.5 88.5T1422 401t89 330q0 174-85.5 325t-239 243-334.5 92q-176 0-328.5-88.5T282 1060t-89-329z"/><glyph unicode="¯" horiz-adv-x="1024" d="M1030 1556H-6v82h1036v-82z"/><glyph unicode="°" horiz-adv-x="877" d="M139 1184q0 132 86.5 215.5T438 1483t212.5-83.5T737 1184t-86.5-215.5T438 885q-130 0-214.5 83T139 1184zm90 0q0-91 61-154t148-63q86 0 147.5 62t61.5 155q0 92-60 154.5T438 1401q-90 0-149.5-64T229 1184z"/><glyph unicode="±" d="M111 1zm0 0v82h948V1H111zm514 763h434v-82H625V250h-82v432H111v82h432v434h82V764z"/><glyph unicode="²" horiz-adv-x="688" d="M629 586H53v78l242 237q125 121 172 193t47 149q0 71-46.5 112.5T344 1397q-108 0-217-82l-49 65q119 103 270 103 124 0 194-63.5t70-174.5q0-47-13-89t-40-85.5-68.5-90T182 674h447v-88z"/><glyph unicode="³" horiz-adv-x="688" d="M616 1260q0-78-44-131.5T455 1053q186-45 186-211 0-130-88.5-201.5T305 569q-144 0-264 60v88q136-62 266-62 115 0 174.5 49T541 840q0 83-59.5 122T303 1001H172v84h135q105 0 158 43.5t53 120.5q0 67-47 107.5T344 1397q-128 0-246-78l-47 70q130 94 293 94 127 0 199.5-60t72.5-163z"/><glyph unicode="´" horiz-adv-x="1182" d="M393 1257q73 79 144.5 171.5T635 1569h141v-17q-36-52-122.5-138T463 1241h-70v16z"/><glyph unicode="µ" horiz-adv-x="1221" d="M281 1087V383q0-164 69-238.5T563 70q194 0 285.5 98T940 487v600h98V0h-84l-18 150h-6Q880 73 780 26.5T563-20q-99 0-167.5 27.5T276 92q5-92 5-170v-414h-99v1579h99z"/><glyph unicode="¶" horiz-adv-x="1341" d="M1106-260h-100v1722H778V-260H678v819q-64-18-146-18-216 0-317.5 125T113 1042q0 260 109 387t341 127h543V-260z"/><glyph unicode="·" horiz-adv-x="487" d="M162 623zm0 98q0 98 80 98 82 0 82-98t-82-98q-80 0-80 98z"/><glyph unicode="¸" horiz-adv-x="420" d="M393-291q0-100-67.5-150.5T137-492q-68 0-94 11v88q30-10 92-10 78 0 119 28t41 80q0 94-193 121L195 0h96l-66-117q168-37 168-174z"/><glyph unicode="¹" horiz-adv-x="688" d="M350 1462h92V586h-98v547q0 99 12 233-26-23-233-145l-47 77z"/><glyph unicode="º" horiz-adv-x="739" d="M670 1141q0-161-80-250.5T367 801t-220 86-77 254q0 162 78 250t223 88q142 0 220.5-87t78.5-251zm-510 0q0-264 209-264t209 264q0 131-50 194.5T369 1399t-159-63.5-50-194.5z"/><glyph unicode="»" horiz-adv-x="885" d="M803 518L494 125l-62 43 254 362-254 363 62 43 309-391v-27zm-361 0L133 125l-61 43 254 362L72 893l61 43 309-391v-27z"/><glyph unicode="¼" horiz-adv-x="1516" d="M59 0zm274 1462h92V586h-98v547q0 99 12 233-26-23-233-145l-47 77zm815 0L337 0h-94l811 1462h94zm244-1220h-129V1h-90v241H760v60l407 581h96V320h129v-78zm-219 78v221q0 132 8 232-6-12-21.5-35.5T864 320h309z"/><glyph unicode="½" horiz-adv-x="1516" d="M11 0zm274 1462h92V586h-98v547q0 99 12 233-26-23-233-145l-47 77zm788 0L262 0h-94l811 1462h94zM1403 1H827v78l242 237q125 121 172 193t47 149q0 71-46.5 112.5T1118 812q-108 0-217-82l-49 65q119 103 270 103 124 0 194-63.5t70-174.5q0-47-13-89t-40-85.5-68.5-90T956 89h447V1z"/><glyph unicode="¾" horiz-adv-x="1516" d="M41 0zm575 1260q0-78-44-131.5T455 1053q186-45 186-211 0-130-88.5-201.5T305 569q-144 0-264 60v88q136-62 266-62 115 0 174.5 49T541 840q0 83-59.5 122T303 1001H172v84h135q105 0 158 43.5t53 120.5q0 67-47 107.5T344 1397q-128 0-246-78l-47 70q130 94 293 94 127 0 199.5-60t72.5-163zm684 202L489 0h-94l811 1462h94zm195-1220h-129V1h-90v241H863v60l407 581h96V320h129v-78zm-219 78v221q0 132 8 232-6-12-21.5-35.5T967 320h309z"/><glyph unicode="¿" horiz-adv-x="862" d="M569 711v-37q0-125-39.5-204.5T393 305l-90-79q-73-61-104-120.5T168-33q0-124 82-200t221-76q125 0 233 46l64 27 37-79q-111-48-185.5-64T467-395q-184 0-288.5 99T74-27q0 70 20 124t58.5 102T324 358q64 53 98.5 98.5t49.5 94T487 696v15h82zm-129 299q0 98 80 98 82 0 82-98 0-53-23.5-76T520 911q-34 0-57 23t-23 76z"/><glyph unicode="À" horiz-adv-x="1229" d="M0 0zm911 516H317L113 0H0l588 1468h65L1229 0h-115zm-557 92h523l-199 527q-25 62-60 172-27-96-59-174zm366 971h-69q-96 79-188.5 171.5T337 1890v17h142q26-48 98.5-142T720 1595v-16z"/><glyph unicode="Á" horiz-adv-x="1229" d="M0 0zm911 516H317L113 0H0l588 1468h65L1229 0h-115zm-557 92h523l-199 527q-25 62-60 172-27-96-59-174zm150 987q73 79 144.5 171.5T746 1907h141v-17q-36-52-122.5-138T574 1579h-70v16z"/><glyph unicode="Â" horiz-adv-x="1229" d="M0 0zm911 516H317L113 0H0l588 1468h65L1229 0h-115zm-557 92h523l-199 527q-25 62-60 172-27-96-59-174zm-26 987q62 67 131.5 156T570 1907h98q68-120 242-312v-16h-70q-122 101-221 207-108-114-221-207h-70v16z"/><glyph unicode="Ã" horiz-adv-x="1229" d="M0 0zm911 516H317L113 0H0l588 1468h65L1229 0h-115zm-557 92h523l-199 527q-25 62-60 172-27-96-59-174zm430 973q-36 0-75 18.5T608 1671q-32 26-62.5 46t-62.5 20q-45 0-75-34.5T360 1581h-73q10 111 63 174.5t137 63.5q48 0 88-25t82-59q34-28 66-50t61-22q46 0 77 36.5t48 119.5h76q-16-116-69-177t-132-61z"/><glyph unicode="Ä" horiz-adv-x="1229" d="M0 0zm911 516H317L113 0H0l588 1468h65L1229 0h-115zm-557 92h523l-199 527q-25 62-60 172-27-96-59-174zm13 1119q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="Å" horiz-adv-x="1229" d="M0 0zm911 516H317L113 0H0l588 1468h65L1229 0h-115zm-557 92h523l-199 527q-25 62-60 172-27-96-59-174zm482 1002q0-97-60-155t-157-58-157 58-60 155q0 94 60 152.5t157 58.5 157-59 60-152zm-354 0q0-66 37.5-103.5T619 1469t99.5 37.5T756 1610q0 64-39 101.5t-98 37.5q-62 0-99.5-38T482 1610z"/><glyph unicode="Æ" horiz-adv-x="1653" d="M1528 0H811v516H336L109 0H-2l653 1462h877v-94H913V815h576v-94H913V94h615V0zM377 608h434v760H711z"/><glyph unicode="Ç" horiz-adv-x="1272" d="M129 0zm702 1391q-275 0-433-176T240 733q0-313 149-486T815 74q184 0 338 47V31q-145-51-362-51-308 0-485 199T129 735q0 223 84.5 393t243 262.5T825 1483q214 0 383-80l-41-92q-160 80-336 80zm80-1682q0-100-67.5-150.5T655-492q-68 0-94 11v88q30-10 92-10 78 0 119 28t41 80q0 94-193 121L713 0h96l-66-117q168-37 168-174z"/><glyph unicode="È" horiz-adv-x="1130" d="M207 0zm799 0H207v1462h799v-94H309V815h658v-94H309V94h697V0zM697 1579h-69q-96 79-188.5 171.5T314 1890v17h142q26-48 98.5-142T697 1595v-16z"/><glyph unicode="É" horiz-adv-x="1130" d="M207 0zm799 0H207v1462h799v-94H309V815h658v-94H309V94h697V0zM463 1595q73 79 144.5 171.5T705 1907h141v-17q-36-52-122.5-138T533 1579h-70v16z"/><glyph unicode="Ê" horiz-adv-x="1130" d="M207 0zm799 0H207v1462h799v-94H309V815h658v-94H309V94h697V0zM315 1595q62 67 131.5 156T557 1907h98q68-120 242-312v-16h-70q-122 101-221 207-108-114-221-207h-70v16z"/><glyph unicode="Ë" horiz-adv-x="1130" d="M207 0zm799 0H207v1462h799v-94H309V815h658v-94H309V94h697V0zM354 1727q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="Ì" horiz-adv-x="516" d="M0 0zm207 0v1462h102V0H207zm113 1579h-69q-96 79-188.5 171.5T-63 1890v17H79q26-48 98.5-142T320 1595v-16z"/><glyph unicode="Í" horiz-adv-x="516" d="M191 0zm16 0v1462h102V0H207zm-16 1595q73 79 144.5 171.5T433 1907h141v-17q-36-52-122.5-138T261 1579h-70v16z"/><glyph unicode="Î" horiz-adv-x="516" d="M0 0zm207 0v1462h102V0H207zM-32 1595q62 67 131.5 156T210 1907h98q68-120 242-312v-16h-70q-122 101-221 207-108-114-221-207h-70v16z"/><glyph unicode="Ï" horiz-adv-x="516" d="M5 0zm202 0v1462h102V0H207zM5 1727q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="Ð" horiz-adv-x="1466" d="M1317 745q0-368-193-556.5T557 0H207v678H47v94h160v690h395q350 0 532.5-183T1317 745zm-111-4q0 314-159.5 472.5T578 1372H309V772h406v-94H309V90h242q655 0 655 651z"/><glyph unicode="Ñ" horiz-adv-x="1477" d="M207 0zm1063 0h-103L301 1298h-8q12-232 12-350V0h-98v1462h102l865-1296h6q-9 180-9 342v954h99V0zM897 1581q-36 0-75 18.5T721 1671q-32 26-62.5 46t-62.5 20q-45 0-75-34.5T473 1581h-73q10 111 63 174.5t137 63.5q48 0 88-25t82-59q34-28 66-50t61-22q46 0 77 36.5t48 119.5h76q-16-116-69-177t-132-61z"/><glyph unicode="Ò" horiz-adv-x="1565" d="M129 0zm1307 733q0-348-174-550.5T782-20q-305 0-479 202.5T129 735q0 349 175.5 549.5T784 1485q306 0 479-201.5T1436 733zm-1196 0q0-314 140-485.5T782 76q264 0 403.5 170T1325 733q0 316-139.5 484.5T784 1386q-261 0-402.5-170T240 733zm645 846h-69q-96 79-188.5 171.5T502 1890v17h142q26-48 98.5-142T885 1595v-16z"/><glyph unicode="Ó" horiz-adv-x="1565" d="M129 0zm1307 733q0-348-174-550.5T782-20q-305 0-479 202.5T129 735q0 349 175.5 549.5T784 1485q306 0 479-201.5T1436 733zm-1196 0q0-314 140-485.5T782 76q264 0 403.5 170T1325 733q0 316-139.5 484.5T784 1386q-261 0-402.5-170T240 733zm446 862q73 79 144.5 171.5T928 1907h141v-17q-36-52-122.5-138T756 1579h-70v16z"/><glyph unicode="Ô" horiz-adv-x="1565" d="M129 0zm1307 733q0-348-174-550.5T782-20q-305 0-479 202.5T129 735q0 349 175.5 549.5T784 1485q306 0 479-201.5T1436 733zm-1196 0q0-314 140-485.5T782 76q264 0 403.5 170T1325 733q0 316-139.5 484.5T784 1386q-261 0-402.5-170T240 733zm252 862q62 67 131.5 156T734 1907h98q68-120 242-312v-16h-70q-122 101-221 207-108-114-221-207h-70v16z"/><glyph unicode="Õ" horiz-adv-x="1565" d="M129 0zm1307 733q0-348-174-550.5T782-20q-305 0-479 202.5T129 735q0 349 175.5 549.5T784 1485q306 0 479-201.5T1436 733zm-1196 0q0-314 140-485.5T782 76q264 0 403.5 170T1325 733q0 316-139.5 484.5T784 1386q-261 0-402.5-170T240 733zm700 848q-36 0-75 18.5T764 1671q-32 26-62.5 46t-62.5 20q-45 0-75-34.5T516 1581h-73q10 111 63 174.5t137 63.5q48 0 88-25t82-59q34-28 66-50t61-22q46 0 77 36.5t48 119.5h76q-16-116-69-177t-132-61z"/><glyph unicode="Ö" horiz-adv-x="1565" d="M129 0zm1307 733q0-348-174-550.5T782-20q-305 0-479 202.5T129 735q0 349 175.5 549.5T784 1485q306 0 479-201.5T1436 733zm-1196 0q0-314 140-485.5T782 76q264 0 403.5 170T1325 733q0 316-139.5 484.5T784 1386q-261 0-402.5-170T240 733zm289 994q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="×" d="M584 780l409 408 58-58-408-407 406-408-58-57-407 408-406-408-57 57 405 408-407 407 57 58z"/><glyph unicode="Ø" horiz-adv-x="1565" d="M1436 733q0-348-174-550.5T782-20q-236 0-395 120L301-20l-74 59 90 127Q129 366 129 735q0 349 175.5 549.5T784 1485q232 0 392-121l108 152 72-60-111-153q191-207 191-570zm-111 0q0 315-139 486L444 182Q577 76 782 76q264 0 403.5 170T1325 733zm-1085 0q0-312 139-483l739 1034q-133 102-334 102-261 0-402.5-170T240 733z"/><glyph unicode="Ù" horiz-adv-x="1473" d="M190 0zm1092 1462V516q0-252-146-394T729-20q-254 0-396.5 142.5T190 520v942h103V516q0-211 117-328.5T741 70q209 0 324 115.5T1180 506v956h102zm-449 117h-69q-96 79-188.5 171.5T450 1890v17h142q26-48 98.5-142T833 1595v-16z"/><glyph unicode="Ú" horiz-adv-x="1473" d="M190 0zm1092 1462V516q0-252-146-394T729-20q-254 0-396.5 142.5T190 520v942h103V516q0-211 117-328.5T741 70q209 0 324 115.5T1180 506v956h102zm-649 133q73 79 144.5 171.5T875 1907h141v-17q-36-52-122.5-138T703 1579h-70v16z"/><glyph unicode="Û" horiz-adv-x="1473" d="M190 0zm1092 1462V516q0-252-146-394T729-20q-254 0-396.5 142.5T190 520v942h103V516q0-211 117-328.5T741 70q209 0 324 115.5T1180 506v956h102zm-838 133q62 67 131.5 156T686 1907h98q68-120 242-312v-16h-70q-122 101-221 207-108-114-221-207h-70v16z"/><glyph unicode="Ü" horiz-adv-x="1473" d="M190 0zm1092 1462V516q0-252-146-394T729-20q-254 0-396.5 142.5T190 520v942h103V516q0-211 117-328.5T741 70q209 0 324 115.5T1180 506v956h102zm-801 265q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="Ý" horiz-adv-x="1081" d="M0 0zm543 662l428 800h110L594 565V0H489v557L0 1462h117zm-109 933q73 79 144.5 171.5T676 1907h141v-17q-36-52-122.5-138T504 1579h-70v16z"/><glyph unicode="Þ" horiz-adv-x="1198" d="M1087 778q0-212-144-325T535 340H309V0H207v1462h102v-264h256q522 0 522-420zM309 428h201q247 0 357 81.5T977 774q0 169-104 250.5T551 1106H309V428z"/><glyph unicode="ß" horiz-adv-x="1194" d="M961 1284q0-139-139-250-81-64-110.5-100.5T682 858q0-44 14.5-68t51.5-57 102-78q106-75 151.5-124.5t68-103T1092 307q0-156-88-241.5T758-20q-95 0-174.5 18.5T457 47v107q65-38 148.5-62T758 68q114 0 174.5 54.5T993 283q0 83-39 144T805 563q-127 87-175 147t-48 146q0 60 32.5 110T721 1074q74 57 106.5 105.5T860 1286q0 93-70 143t-202 50q-145 0-226-69t-81-196V0h-99v1206q0 173 103.5 267t292.5 94q188 0 285.5-72.5T961 1284z"/><glyph unicode="à" horiz-adv-x="1085" d="M98 0zm744 0l-25 172h-8Q727 67 640.5 23.5T436-20q-160 0-249 82T98 289q0 159 132.5 247T614 629l207 6v72q0 155-63 234t-203 79q-151 0-313-84l-37 86q179 84 354 84 179 0 267.5-93T915 723V0h-73zM442 70q174 0 274.5 99.5T817 446v107l-190-8q-229-11-326.5-71.5T203 285q0-102 62.5-158.5T442 70zm196 1171h-69q-96 79-188.5 171.5T255 1552v17h142q26-48 98.5-142T638 1257v-16z"/><glyph unicode="á" horiz-adv-x="1085" d="M98 0zm744 0l-25 172h-8Q727 67 640.5 23.5T436-20q-160 0-249 82T98 289q0 159 132.5 247T614 629l207 6v72q0 155-63 234t-203 79q-151 0-313-84l-37 86q179 84 354 84 179 0 267.5-93T915 723V0h-73zM442 70q174 0 274.5 99.5T817 446v107l-190-8q-229-11-326.5-71.5T203 285q0-102 62.5-158.5T442 70zm-20 1187q73 79 144.5 171.5T664 1569h141v-17q-36-52-122.5-138T492 1241h-70v16z"/><glyph unicode="â" horiz-adv-x="1085" d="M98 0zm744 0l-25 172h-8Q727 67 640.5 23.5T436-20q-160 0-249 82T98 289q0 159 132.5 247T614 629l207 6v72q0 155-63 234t-203 79q-151 0-313-84l-37 86q179 84 354 84 179 0 267.5-93T915 723V0h-73zM442 70q174 0 274.5 99.5T817 446v107l-190-8q-229-11-326.5-71.5T203 285q0-102 62.5-158.5T442 70zM251 1257q62 67 131.5 156T493 1569h98q68-120 242-312v-16h-70q-122 101-221 207-108-114-221-207h-70v16z"/><glyph unicode="ã" horiz-adv-x="1085" d="M98 0zm744 0l-25 172h-8Q727 67 640.5 23.5T436-20q-160 0-249 82T98 289q0 159 132.5 247T614 629l207 6v72q0 155-63 234t-203 79q-151 0-313-84l-37 86q179 84 354 84 179 0 267.5-93T915 723V0h-73zM442 70q174 0 274.5 99.5T817 446v107l-190-8q-229-11-326.5-71.5T203 285q0-102 62.5-158.5T442 70zm255 1173q-36 0-75 18.5T521 1333q-32 26-62.5 46t-62.5 20q-45 0-75-34.5T273 1243h-73q10 111 63 174.5t137 63.5q48 0 88-25t82-59q34-28 66-50t61-22q46 0 77 36.5t48 119.5h76q-16-116-69-177t-132-61z"/><glyph unicode="ä" horiz-adv-x="1085" d="M98 0zm744 0l-25 172h-8Q727 67 640.5 23.5T436-20q-160 0-249 82T98 289q0 159 132.5 247T614 629l207 6v72q0 155-63 234t-203 79q-151 0-313-84l-37 86q179 84 354 84 179 0 267.5-93T915 723V0h-73zM442 70q174 0 274.5 99.5T817 446v107l-190-8q-229-11-326.5-71.5T203 285q0-102 62.5-158.5T442 70zM282 1389q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="å" horiz-adv-x="1085" d="M98 0zm744 0l-25 172h-8Q727 67 640.5 23.5T436-20q-160 0-249 82T98 289q0 159 132.5 247T614 629l207 6v72q0 155-63 234t-203 79q-151 0-313-84l-37 86q179 84 354 84 179 0 267.5-93T915 723V0h-73zM442 70q174 0 274.5 99.5T817 446v107l-190-8q-229-11-326.5-71.5T203 285q0-102 62.5-158.5T442 70zm317 1386q0-97-60-155t-157-58-157 58-60 155q0 94 60 152.5t157 58.5 157-59 60-152zm-354 0q0-66 37.5-103.5T542 1315t99.5 37.5T679 1456q0 64-39 101.5t-98 37.5q-62 0-99.5-38T405 1456z"/><glyph unicode="æ" horiz-adv-x="1731" d="M1243-20q-295 0-397 256-68-133-168-194.5T426-20q-156 0-242 82.5T98 289q0 154 125 243t377 97l201 6v72q0 155-61.5 234T541 1020q-148 0-305-84l-37 86q173 84 346 84 261 0 325-211 111 213 347 213 184 0 289.5-134.5T1612 610v-80H897q0-460 348-460 85 0 150 12t174 57V49q-92-41-165-55t-161-14zM434 70q169 0 266 99.5T797 446v107l-187-8q-219-11-313-71.5T203 285q0-102 61-158.5T434 70zm783 950q-284 0-314-402h604q0 188-77.5 295T1217 1020z"/><glyph unicode="ç" horiz-adv-x="973" d="M119 0zm497-20q-233 0-365 147T119 537q0 270 137 420.5T631 1108q141 0 270-49l-27-88q-141 47-245 47-200 0-303-123.5T223 539q0-220 103-344.5T614 70q148 0 275 53V31Q785-20 616-20zm107-271q0-100-67.5-150.5T467-492q-68 0-94 11v88q30-10 92-10 78 0 119 28t41 80q0 94-193 121L525 0h96l-66-117q168-37 168-174z"/><glyph unicode="è" horiz-adv-x="1124" d="M119 0zm502-20q-237 0-369.5 146T119 535q0 260 128 416.5T592 1108q192 0 303-134t111-364v-80H223q2-224 104.5-342T621 70q93 0 163.5 13T963 139V49Q871 9 793-5.5T621-20zm-29 1040q-157 0-252-103.5T229 618h672q0 189-82 295.5T592 1020zm93 221h-69q-96 79-188.5 171.5T302 1552v17h142q26-48 98.5-142T685 1257v-16z"/><glyph unicode="é" horiz-adv-x="1124" d="M119 0zm502-20q-237 0-369.5 146T119 535q0 260 128 416.5T592 1108q192 0 303-134t111-364v-80H223q2-224 104.5-342T621 70q93 0 163.5 13T963 139V49Q871 9 793-5.5T621-20zm-29 1040q-157 0-252-103.5T229 618h672q0 189-82 295.5T592 1020zm-140 237q73 79 144.5 171.5T694 1569h141v-17q-36-52-122.5-138T522 1241h-70v16z"/><glyph unicode="ê" horiz-adv-x="1124" d="M119 0zm502-20q-237 0-369.5 146T119 535q0 260 128 416.5T592 1108q192 0 303-134t111-364v-80H223q2-224 104.5-342T621 70q93 0 163.5 13T963 139V49Q871 9 793-5.5T621-20zm-29 1040q-157 0-252-103.5T229 618h672q0 189-82 295.5T592 1020zm-302 237q62 67 131.5 156T532 1569h98q68-120 242-312v-16h-70q-122 101-221 207-108-114-221-207h-70v16z"/><glyph unicode="ë" horiz-adv-x="1124" d="M119 0zm502-20q-237 0-369.5 146T119 535q0 260 128 416.5T592 1108q192 0 303-134t111-364v-80H223q2-224 104.5-342T621 70q93 0 163.5 13T963 139V49Q871 9 793-5.5T621-20zm-29 1040q-157 0-252-103.5T229 618h672q0 189-82 295.5T592 1020zm-261 369q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="ì" horiz-adv-x="463" d="M0 0zm281 0h-99v1087h99V0zm68 1241h-69q-96 79-188.5 171.5T-34 1552v17h142q26-48 98.5-142T349 1257v-16z"/><glyph unicode="í" horiz-adv-x="463" d="M107 0zm174 0h-99v1087h99V0zM107 1257q73 79 144.5 171.5T349 1569h141v-17q-36-52-122.5-138T177 1241h-70v16z"/><glyph unicode="î" horiz-adv-x="463" d="M0 0zm281 0h-99v1087h99V0zM-58 1257q62 67 131.5 156T184 1569h98q68-120 242-312v-16h-70q-122 101-221 207-108-114-221-207h-70v16z"/><glyph unicode="ï" horiz-adv-x="463" d="M0 0zm281 0h-99v1087h99V0zM-21 1389q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="ð" horiz-adv-x="1174" d="M1055 559q0-276-124-427.5T582-20q-214 0-339.5 130T117 471q0 228 126.5 357.5T586 958q108 0 187.5-33T922 829l4 2q-64 270-269 459l-270-157-49 77 244 146q-86 62-199 119l45 81q147-69 248-145l225 137 49-84-202-121q154-151 230.5-353t76.5-431zm-105-2q0 146-97 228.5T586 868q-185 0-275-100.5T221 463q0-186 94.5-289.5T584 70q179 0 272.5 123T950 557z"/><glyph unicode="ñ" horiz-adv-x="1208" d="M182 0zm758 0v705q0 164-69 238.5T657 1018q-195 0-285.5-98.5T281 600V0h-99v1087h84l19-149h6q106 170 377 170 370 0 370-397V0h-98zM779 1243q-36 0-75 18.5T603 1333q-32 26-62.5 46t-62.5 20q-45 0-75-34.5T355 1243h-73q10 111 63 174.5t137 63.5q48 0 88-25t82-59q34-28 66-50t61-22q46 0 77 36.5t48 119.5h76q-16-116-69-177t-132-61z"/><glyph unicode="ò" horiz-adv-x="1200" d="M119 0zm962 545q0-266-129-415.5T596-20q-143 0-252 69T177 247t-58 298q0 266 129 414.5T602 1108q224 0 351.5-150.5T1081 545zm-858 0q0-224 98.5-349.5T600 70t278.5 125.5T977 545q0 225-99.5 349T598 1018 320.5 894.5 223 545zm495 696h-69q-96 79-188.5 171.5T335 1552v17h142q26-48 98.5-142T718 1257v-16z"/><glyph unicode="ó" horiz-adv-x="1200" d="M119 0zm962 545q0-266-129-415.5T596-20q-143 0-252 69T177 247t-58 298q0 266 129 414.5T602 1108q224 0 351.5-150.5T1081 545zm-858 0q0-224 98.5-349.5T600 70t278.5 125.5T977 545q0 225-99.5 349T598 1018 320.5 894.5 223 545zm276 712q73 79 144.5 171.5T741 1569h141v-17q-36-52-122.5-138T569 1241h-70v16z"/><glyph unicode="ô" horiz-adv-x="1200" d="M119 0zm962 545q0-266-129-415.5T596-20q-143 0-252 69T177 247t-58 298q0 266 129 414.5T602 1108q224 0 351.5-150.5T1081 545zm-858 0q0-224 98.5-349.5T600 70t278.5 125.5T977 545q0 225-99.5 349T598 1018 320.5 894.5 223 545zm86 712q62 67 131.5 156T551 1569h98q68-120 242-312v-16h-70q-122 101-221 207-108-114-221-207h-70v16z"/><glyph unicode="õ" horiz-adv-x="1200" d="M119 0zm962 545q0-266-129-415.5T596-20q-143 0-252 69T177 247t-58 298q0 266 129 414.5T602 1108q224 0 351.5-150.5T1081 545zm-858 0q0-224 98.5-349.5T600 70t278.5 125.5T977 545q0 225-99.5 349T598 1018 320.5 894.5 223 545zm538 698q-36 0-75 18.5T585 1333q-32 26-62.5 46t-62.5 20q-45 0-75-34.5T337 1243h-73q10 111 63 174.5t137 63.5q48 0 88-25t82-59q34-28 66-50t61-22q46 0 77 36.5t48 119.5h76q-16-116-69-177t-132-61z"/><glyph unicode="ö" horiz-adv-x="1200" d="M119 0zm962 545q0-266-129-415.5T596-20q-143 0-252 69T177 247t-58 298q0 266 129 414.5T602 1108q224 0 351.5-150.5T1081 545zm-858 0q0-224 98.5-349.5T600 70t278.5 125.5T977 545q0 225-99.5 349T598 1018 320.5 894.5 223 545zm123 844q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="÷" d="M111 682v82h948v-82H111zm393 393q0 99 80 99 82 0 82-99 0-52-23.5-75T584 977q-34 0-57 23t-23 75zm0-704q0 98 80 98 82 0 82-98 0-53-23.5-76T584 272q-34 0-57 23t-23 76z"/><glyph unicode="ø" horiz-adv-x="1200" d="M1081 545q0-266-129-415.5T596-20q-173 0-291 98L219-35l-72 58 93 120Q119 296 119 545q0 266 129 414.5T602 1108q179 0 301-104l96 124 74-55-104-137q112-147 112-391zm-858 0q0-200 78-322l543 705q-98 90-246 90-180 0-277.5-123.5T223 545zm754 0q0 190-72 309L362 152q94-82 238-82 180 0 278.5 125.5T977 545z"/><glyph unicode="ù" horiz-adv-x="1208" d="M170 0zm98 1087V383q0-164 69-238.5T551 70q194 0 285.5 98T928 487v600h98V0h-84l-18 150h-6Q812-20 541-20q-371 0-371 397v710h98zm419 154h-69q-96 79-188.5 171.5T304 1552v17h142q26-48 98.5-142T687 1257v-16z"/><glyph unicode="ú" horiz-adv-x="1208" d="M170 0zm98 1087V383q0-164 69-238.5T551 70q194 0 285.5 98T928 487v600h98V0h-84l-18 150h-6Q812-20 541-20q-371 0-371 397v710h98zm227 170q73 79 144.5 171.5T737 1569h141v-17q-36-52-122.5-138T565 1241h-70v16z"/><glyph unicode="û" horiz-adv-x="1208" d="M170 0zm98 1087V383q0-164 69-238.5T551 70q194 0 285.5 98T928 487v600h98V0h-84l-18 150h-6Q812-20 541-20q-371 0-371 397v710h98zm45 170q62 67 131.5 156T555 1569h98q68-120 242-312v-16h-70q-122 101-221 207-108-114-221-207h-70v16z"/><glyph unicode="ü" horiz-adv-x="1208" d="M170 0zm98 1087V383q0-164 69-238.5T551 70q194 0 285.5 98T928 487v600h98V0h-84l-18 150h-6Q812-20 541-20q-371 0-371 397v710h98zm82 302q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="ý" horiz-adv-x="940" d="M0 0zm0 1087h102l230-610Q437 196 465 98h6q42 129 137 385l230 604h102L453-176q-59-154-99-208t-93.5-81T131-492q-57 0-127 21v86q58-16 125-16 51 0 90 24t70.5 74.5 73 160T416 0zm361 170q73 79 144.5 171.5T603 1569h141v-17q-36-52-122.5-138T431 1241h-70v16z"/><glyph unicode="þ" horiz-adv-x="1219" d="M281 918q114 190 368 190 220 0 335.5-144.5T1100 543q0-268-121.5-415.5T647-20q-251 0-366 188h-7l3-84q4-74 4-162v-414h-99v2048h99v-391l-7-247h7zM645 68q167 0 258.5 124T995 539q0 479-348 479-193 0-279.5-105T281 559v-18q0-255 85.5-364T645 68z"/><glyph unicode="ÿ" horiz-adv-x="940" d="M0 0zm0 1087h102l230-610Q437 196 465 98h6q42 129 137 385l230 604h102L453-176q-59-154-99-208t-93.5-81T131-492q-57 0-127 21v86q58-16 125-16 51 0 90 24t70.5 74.5 73 160T416 0zm214 302q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="ı" horiz-adv-x="463" d="M281 0h-99v1087h99V0z"/><glyph unicode="Œ" horiz-adv-x="1839" d="M1714 0H958q-76-16-176-16-305 0-479 200T129 735q0 347 174.5 545.5T784 1479q78 0 183-17h747v-94h-655V815h616v-94h-616V94h655V0zM782 80q109 0 174 18v1266q-62 16-172 16-262 0-403-167.5T240 733q0-315 140.5-484T782 80z"/><glyph unicode="œ" horiz-adv-x="1942" d="M1438-20q-156 0-266.5 67.5T1006 246Q947 118 848 49T596-20q-143 0-252 69T177 247t-58 298q0 266 129 414.5T602 1108q151 0 251-70t157-209q110 279 399 279 192 0 303-134t111-364v-80h-762q2-230 100.5-345T1438 70q93 0 163.5 13t178.5 56V49q-92-40-170-54.5T1438-20zM223 545q0-224 98.5-349.5T600 70q174 0 265 122.5T956 545q0 224-93 348.5T598 1018q-180 0-277.5-123.5T223 545zm1186 475q-155 0-242-104t-102-298h653q0 189-82 295.5T1409 1020z"/><glyph unicode="Ÿ" horiz-adv-x="1081" d="M0 0zm543 662l428 800h110L594 565V0H489v557L0 1462h117zM288 1727q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86zm381 0q0 46 15.5 66t47.5 20q64 0 64-86t-64-86q-63 0-63 86z"/><glyph unicode="ˆ" horiz-adv-x="1182" d="M299 1257q62 67 131.5 156T541 1569h98q68-120 242-312v-16h-70q-122 101-221 207-108-114-221-207h-70v16z"/><glyph unicode="˚" horiz-adv-x="1182" d="M805 1456q0-97-60-155t-157-58-157 58-60 155q0 94 60 152.5t157 58.5 157-59 60-152zm-354 0q0-66 37.5-103.5T588 1315t99.5 37.5T725 1456q0 64-39 101.5t-98 37.5q-62 0-99.5-38T451 1456z"/><glyph unicode="˜" horiz-adv-x="1182" d="M780 1243q-36 0-75 18.5T604 1333q-32 26-62.5 46t-62.5 20q-45 0-75-34.5T356 1243h-73q10 111 63 174.5t137 63.5q48 0 88-25t82-59q34-28 66-50t61-22q46 0 77 36.5t48 119.5h76q-16-116-69-177t-132-61z"/><glyph horiz-adv-x="953"/><glyph horiz-adv-x="1907"/><glyph horiz-adv-x="953"/><glyph horiz-adv-x="1907"/><glyph horiz-adv-x="635"/><glyph horiz-adv-x="476"/><glyph horiz-adv-x="317"/><glyph horiz-adv-x="317"/><glyph horiz-adv-x="238"/><glyph horiz-adv-x="381"/><glyph horiz-adv-x="105"/><glyph unicode="‐" horiz-adv-x="659" d="M92 512v82h475v-82H92z"/><glyph unicode="‑" horiz-adv-x="659" d="M92 512v82h475v-82H92z"/><glyph unicode="‒" horiz-adv-x="659" d="M92 512v82h475v-82H92z"/><glyph unicode="–" horiz-adv-x="1024" d="M82 512v82h860v-82H82z"/><glyph unicode="—" horiz-adv-x="2048" d="M82 512v82h1884v-82H82z"/><glyph unicode="‘" horiz-adv-x="297" d="M41 961l-12 20q32 112 81.5 251t92.5 230h65q-30-101-64.5-257T158 961H41z"/><glyph unicode="’" horiz-adv-x="297" d="M256 1462l12-20q-75-265-174-481H29q29 96 61 241.5t49 259.5h117z"/><glyph unicode="‚" horiz-adv-x="451" d="M68 0zm227 238l12-20Q232-47 133-263H68q29 96 61 241.5T178 238h117z"/><glyph unicode="“" horiz-adv-x="614" d="M358 961l-12 20q34 120 83 255t91 226h66q-30-98-63-248.5T475 961H358zm-317 0l-12 20q32 112 81.5 251t92.5 230h65q-30-101-64.5-257T158 961H41z"/><glyph unicode="”" horiz-adv-x="614" d="M256 1462l12-20q-75-265-174-481H29q29 96 61 241.5t49 259.5h117zm317 0l13-20q-36-128-85-261t-89-220h-66q30 98 63 248.5t48 252.5h116z"/><glyph unicode="„" horiz-adv-x="768" d="M68 0zm227 238l12-20Q232-47 133-263H68q29 96 61 241.5T178 238h117zm317 0l13-20Q589 90 540-43t-89-220h-66q30 98 63 248.5T496 238h116z"/><glyph unicode="•" horiz-adv-x="770" d="M231 748q0 89 40.5 134.5T385 928t113.5-47T539 748q0-85-41-133t-113-48-113 47-41 134z"/><glyph unicode="…" horiz-adv-x="1466" d="M162 0zm0 78q0 98 80 98 82 0 82-98t-82-98q-80 0-80 98zm489 0q0 98 80 98 82 0 82-98t-82-98q-80 0-80 98zm490 0q0 98 80 98 82 0 82-98t-82-98q-80 0-80 98z"/><glyph horiz-adv-x="381"/><glyph unicode="‹" horiz-adv-x="524" d="M82 543l309 393 62-43-254-363 254-362-62-43L82 516v27z"/><glyph unicode="›" horiz-adv-x="524" d="M442 518L133 125l-61 43 254 362L72 893l61 43 309-391v-27z"/><glyph unicode="⁄" horiz-adv-x="246" d="M573 1462L-238 0h-94l811 1462h94z"/><glyph horiz-adv-x="476"/><glyph unicode="⁴" horiz-adv-x="688" d="M657 827H528V586h-90v241H25v60l407 581h96V905h129v-78zm-219 78v221q0 132 8 232-6-12-21.5-35.5T129 905h309z"/><glyph unicode="€" d="M803 1397q-174 0-288-125.5T360 907h502v-82H352l-4-104v-24q0-65 4-87h449v-82H358q30-217 147.5-338.5T807 68q148 0 287 65V39Q1013 5 943.5-7.5T803-20q-228 0-367.5 140T254 528H74v82h172q-4 38-4 113l4 102H74v82h184q39 272 183 425t362 153q88 0 161-17t148-57l-39-86q-132 72-270 72z"/><glyph unicode="™" horiz-adv-x="1485" d="M313 741h-86v643H10v78h522v-78H313V741zm600 0l-221 609h-6l4-201V741h-82v721h125l221-606 224 606h125V741h-86v398l4 207h-7L987 741h-74z"/><glyph unicode="−" d="M111 682v82h948v-82H111z"/><glyph unicode="" horiz-adv-x="1085" d="M0 1085h1085V0H0v1085z"/><glyph horiz-adv-x="1219" d="M0 0z"/><hkern u1="&quot;" u2="Ÿ" k="-20"/><hkern u1="&quot;" u2="œ" k="123"/><hkern u1="&quot;" u2="ü" k="61"/><hkern u1="&quot;" u2="û" k="61"/><hkern u1="&quot;" u2="ú" k="61"/><hkern u1="&quot;" u2="ù" k="61"/><hkern u1="&quot;" u2="ø" k="123"/><hkern u1="&quot;" u2="ö" k="123"/><hkern u1="&quot;" u2="õ" k="123"/><hkern u1="&quot;" u2="ô" k="123"/><hkern u1="&quot;" u2="ó" k="123"/><hkern u1="&quot;" u2="ò" k="123"/><hkern u1="&quot;" u2="ë" k="123"/><hkern u1="&quot;" u2="ê" k="123"/><hkern u1="&quot;" u2="é" k="123"/><hkern u1="&quot;" u2="è" k="123"/><hkern u1="&quot;" u2="ç" k="123"/><hkern u1="&quot;" u2="æ" k="82"/><hkern u1="&quot;" u2="å" k="82"/><hkern u1="&quot;" u2="ä" k="82"/><hkern u1="&quot;" u2="ã" k="82"/><hkern u1="&quot;" u2="â" k="82"/><hkern u1="&quot;" u2="á" k="82"/><hkern u1="&quot;" u2="à" k="123"/><hkern u1="&quot;" u2="Ý" k="-20"/><hkern u1="&quot;" u2="Å" k="143"/><hkern u1="&quot;" u2="Ä" k="143"/><hkern u1="&quot;" u2="Ã" k="143"/><hkern u1="&quot;" u2="Â" k="143"/><hkern u1="&quot;" u2="Á" k="143"/><hkern u1="&quot;" u2="À" k="143"/><hkern u1="&quot;" u2="u" k="61"/><hkern u1="&quot;" u2="s" k="61"/><hkern u1="&quot;" u2="r" k="61"/><hkern u1="&quot;" u2="q" k="123"/><hkern u1="&quot;" u2="p" k="61"/><hkern u1="&quot;" u2="o" k="123"/><hkern u1="&quot;" u2="n" k="61"/><hkern u1="&quot;" u2="m" k="61"/><hkern u1="&quot;" u2="g" k="61"/><hkern u1="&quot;" u2="e" k="123"/><hkern u1="&quot;" u2="d" k="123"/><hkern u1="&quot;" u2="c" k="123"/><hkern u1="&quot;" u2="a" k="82"/><hkern u1="&quot;" u2="Y" k="-20"/><hkern u1="&quot;" u2="W" k="-41"/><hkern u1="&quot;" u2="V" k="-41"/><hkern u1="&quot;" u2="T" k="-41"/><hkern u1="&quot;" u2="A" k="143"/><hkern u1="'" u2="Ÿ" k="-20"/><hkern u1="'" u2="œ" k="123"/><hkern u1="'" u2="ü" k="61"/><hkern u1="'" u2="û" k="61"/><hkern u1="'" u2="ú" k="61"/><hkern u1="'" u2="ù" k="61"/><hkern u1="'" u2="ø" k="123"/><hkern u1="'" u2="ö" k="123"/><hkern u1="'" u2="õ" k="123"/><hkern u1="'" u2="ô" k="123"/><hkern u1="'" u2="ó" k="123"/><hkern u1="'" u2="ò" k="123"/><hkern u1="'" u2="ë" k="123"/><hkern u1="'" u2="ê" k="123"/><hkern u1="'" u2="é" k="123"/><hkern u1="'" u2="è" k="123"/><hkern u1="'" u2="ç" k="123"/><hkern u1="'" u2="æ" k="82"/><hkern u1="'" u2="å" k="82"/><hkern u1="'" u2="ä" k="82"/><hkern u1="'" u2="ã" k="82"/><hkern u1="'" u2="â" k="82"/><hkern u1="'" u2="á" k="82"/><hkern u1="'" u2="à" k="123"/><hkern u1="'" u2="Ý" k="-20"/><hkern u1="'" u2="Å" k="143"/><hkern u1="'" u2="Ä" k="143"/><hkern u1="'" u2="Ã" k="143"/><hkern u1="'" u2="Â" k="143"/><hkern u1="'" u2="Á" k="143"/><hkern u1="'" u2="À" k="143"/><hkern u1="'" u2="u" k="61"/><hkern u1="'" u2="s" k="61"/><hkern u1="'" u2="r" k="61"/><hkern u1="'" u2="q" k="123"/><hkern u1="'" u2="p" k="61"/><hkern u1="'" u2="o" k="123"/><hkern u1="'" u2="n" k="61"/><hkern u1="'" u2="m" k="61"/><hkern u1="'" u2="g" k="61"/><hkern u1="'" u2="e" k="123"/><hkern u1="'" u2="d" k="123"/><hkern u1="'" u2="c" k="123"/><hkern u1="'" u2="a" k="82"/><hkern u1="'" u2="Y" k="-20"/><hkern u1="'" u2="W" k="-41"/><hkern u1="'" u2="V" k="-41"/><hkern u1="'" u2="T" k="-41"/><hkern u1="'" u2="A" k="143"/><hkern u1="(" u2="J" k="-184"/><hkern u1="," u2="Ÿ" k="123"/><hkern u1="," u2="Œ" k="102"/><hkern u1="," u2="Ý" k="123"/><hkern u1="," u2="Ü" k="41"/><hkern u1="," u2="Û" k="41"/><hkern u1="," u2="Ú" k="41"/><hkern u1="," u2="Ù" k="41"/><hkern u1="," u2="Ø" k="102"/><hkern u1="," u2="Ö" k="102"/><hkern u1="," u2="Õ" k="102"/><hkern u1="," u2="Ô" k="102"/><hkern u1="," u2="Ó" k="102"/><hkern u1="," u2="Ò" k="102"/><hkern u1="," u2="Ç" k="102"/><hkern u1="," u2="Y" k="123"/><hkern u1="," u2="W" k="123"/><hkern u1="," u2="V" k="123"/><hkern u1="," u2="U" k="41"/><hkern u1="," u2="T" k="143"/><hkern u1="," u2="Q" k="102"/><hkern u1="," u2="O" k="102"/><hkern u1="," u2="G" k="102"/><hkern u1="," u2="C" k="102"/><hkern u1="-" u2="T" k="82"/><hkern u1="." u2="Ÿ" k="123"/><hkern u1="." u2="Œ" k="102"/><hkern u1="." u2="Ý" k="123"/><hkern u1="." u2="Ü" k="41"/><hkern u1="." u2="Û" k="41"/><hkern u1="." u2="Ú" k="41"/><hkern u1="." u2="Ù" k="41"/><hkern u1="." u2="Ø" k="102"/><hkern u1="." u2="Ö" k="102"/><hkern u1="." u2="Õ" k="102"/><hkern u1="." u2="Ô" k="102"/><hkern u1="." u2="Ó" k="102"/><hkern u1="." u2="Ò" k="102"/><hkern u1="." u2="Ç" k="102"/><hkern u1="." u2="Y" k="123"/><hkern u1="." u2="W" k="123"/><hkern u1="." u2="V" k="123"/><hkern u1="." u2="U" k="41"/><hkern u1="." u2="T" k="143"/><hkern u1="." u2="Q" k="102"/><hkern u1="." u2="O" k="102"/><hkern u1="." u2="G" k="102"/><hkern u1="." u2="C" k="102"/><hkern u1="A" u2="”" k="143"/><hkern u1="A" u2="’" k="143"/><hkern u1="A" u2="Ÿ" k="123"/><hkern u1="A" u2="Œ" k="41"/><hkern u1="A" u2="Ý" k="123"/><hkern u1="A" u2="Ø" k="41"/><hkern u1="A" u2="Ö" k="41"/><hkern u1="A" u2="Õ" k="41"/><hkern u1="A" u2="Ô" k="41"/><hkern u1="A" u2="Ó" k="41"/><hkern u1="A" u2="Ò" k="41"/><hkern u1="A" u2="Ç" k="41"/><hkern u1="A" u2="Y" k="123"/><hkern u1="A" u2="W" k="82"/><hkern u1="A" u2="V" k="82"/><hkern u1="A" u2="T" k="143"/><hkern u1="A" u2="Q" k="41"/><hkern u1="A" u2="O" k="41"/><hkern u1="A" u2="J" k="-266"/><hkern u1="A" u2="G" k="41"/><hkern u1="A" u2="C" k="41"/><hkern u1="A" u2="'" k="143"/><hkern u1="A" u2="&quot;" k="143"/><hkern u1="B" u2="„" k="82"/><hkern u1="B" u2="‚" k="82"/><hkern u1="B" u2="Ÿ" k="20"/><hkern u1="B" u2="Ý" k="20"/><hkern u1="B" u2="Å" k="41"/><hkern u1="B" u2="Ä" k="41"/><hkern u1="B" u2="Ã" k="41"/><hkern u1="B" u2="Â" k="41"/><hkern u1="B" u2="Á" k="41"/><hkern u1="B" u2="À" k="41"/><hkern u1="B" u2="Z" k="20"/><hkern u1="B" u2="Y" k="20"/><hkern u1="B" u2="X" k="41"/><hkern u1="B" u2="W" k="20"/><hkern u1="B" u2="V" k="20"/><hkern u1="B" u2="T" k="61"/><hkern u1="B" u2="A" k="41"/><hkern u1="B" u2="." k="82"/><hkern u1="B" u2="," k="82"/><hkern u1="C" u2="Œ" k="41"/><hkern u1="C" u2="Ø" k="41"/><hkern u1="C" u2="Ö" k="41"/><hkern u1="C" u2="Õ" k="41"/><hkern u1="C" u2="Ô" k="41"/><hkern u1="C" u2="Ó" k="41"/><hkern u1="C" u2="Ò" k="41"/><hkern u1="C" u2="Ç" k="41"/><hkern u1="C" u2="Q" k="41"/><hkern u1="C" u2="O" k="41"/><hkern u1="C" u2="G" k="41"/><hkern u1="C" u2="C" k="41"/><hkern u1="D" u2="„" k="82"/><hkern u1="D" u2="‚" k="82"/><hkern u1="D" u2="Ÿ" k="20"/><hkern u1="D" u2="Ý" k="20"/><hkern u1="D" u2="Å" k="41"/><hkern u1="D" u2="Ä" k="41"/><hkern u1="D" u2="Ã" k="41"/><hkern u1="D" u2="Â" k="41"/><hkern u1="D" u2="Á" k="41"/><hkern u1="D" u2="À" k="41"/><hkern u1="D" u2="Z" k="20"/><hkern u1="D" u2="Y" k="20"/><hkern u1="D" u2="X" k="41"/><hkern u1="D" u2="W" k="20"/><hkern u1="D" u2="V" k="20"/><hkern u1="D" u2="T" k="61"/><hkern u1="D" u2="A" k="41"/><hkern u1="D" u2="." k="82"/><hkern u1="D" u2="," k="82"/><hkern u1="E" u2="J" k="-123"/><hkern u1="F" u2="„" k="123"/><hkern u1="F" u2="‚" k="123"/><hkern u1="F" u2="Å" k="41"/><hkern u1="F" u2="Ä" k="41"/><hkern u1="F" u2="Ã" k="41"/><hkern u1="F" u2="Â" k="41"/><hkern u1="F" u2="Á" k="41"/><hkern u1="F" u2="À" k="41"/><hkern u1="F" u2="A" k="41"/><hkern u1="F" u2="?" k="-41"/><hkern u1="F" u2="." k="123"/><hkern u1="F" u2="," k="123"/><hkern u1="K" u2="Œ" k="41"/><hkern u1="K" u2="Ø" k="41"/><hkern u1="K" u2="Ö" k="41"/><hkern u1="K" u2="Õ" k="41"/><hkern u1="K" u2="Ô" k="41"/><hkern u1="K" u2="Ó" k="41"/><hkern u1="K" u2="Ò" k="41"/><hkern u1="K" u2="Ç" k="41"/><hkern u1="K" u2="Q" k="41"/><hkern u1="K" u2="O" k="41"/><hkern u1="K" u2="G" k="41"/><hkern u1="K" u2="C" k="41"/><hkern u1="L" u2="”" k="164"/><hkern u1="L" u2="’" k="164"/><hkern u1="L" u2="Ÿ" k="61"/><hkern u1="L" u2="Œ" k="41"/><hkern u1="L" u2="Ý" k="61"/><hkern u1="L" u2="Ü" k="20"/><hkern u1="L" u2="Û" k="20"/><hkern u1="L" u2="Ú" k="20"/><hkern u1="L" u2="Ù" k="20"/><hkern u1="L" u2="Ø" k="41"/><hkern u1="L" u2="Ö" k="41"/><hkern u1="L" u2="Õ" k="41"/><hkern u1="L" u2="Ô" k="41"/><hkern u1="L" u2="Ó" k="41"/><hkern u1="L" u2="Ò" k="41"/><hkern u1="L" u2="Ç" k="41"/><hkern u1="L" u2="Y" k="61"/><hkern u1="L" u2="W" k="41"/><hkern u1="L" u2="V" k="41"/><hkern u1="L" u2="U" k="20"/><hkern u1="L" u2="T" k="41"/><hkern u1="L" u2="Q" k="41"/><hkern u1="L" u2="O" k="41"/><hkern u1="L" u2="G" k="41"/><hkern u1="L" u2="C" k="41"/><hkern u1="L" u2="'" k="164"/><hkern u1="L" u2="&quot;" k="164"/><hkern u1="O" u2="„" k="82"/><hkern u1="O" u2="‚" k="82"/><hkern u1="O" u2="Ÿ" k="20"/><hkern u1="O" u2="Ý" k="20"/><hkern u1="O" u2="Å" k="41"/><hkern u1="O" u2="Ä" k="41"/><hkern u1="O" u2="Ã" k="41"/><hkern u1="O" u2="Â" k="41"/><hkern u1="O" u2="Á" k="41"/><hkern u1="O" u2="À" k="41"/><hkern u1="O" u2="Z" k="20"/><hkern u1="O" u2="Y" k="20"/><hkern u1="O" u2="X" k="41"/><hkern u1="O" u2="W" k="20"/><hkern u1="O" u2="V" k="20"/><hkern u1="O" u2="T" k="61"/><hkern u1="O" u2="A" k="41"/><hkern u1="O" u2="." k="82"/><hkern u1="O" u2="," k="82"/><hkern u1="P" u2="„" k="266"/><hkern u1="P" u2="‚" k="266"/><hkern u1="P" u2="Å" k="102"/><hkern u1="P" u2="Ä" k="102"/><hkern u1="P" u2="Ã" k="102"/><hkern u1="P" u2="Â" k="102"/><hkern u1="P" u2="Á" k="102"/><hkern u1="P" u2="À" k="102"/><hkern u1="P" u2="Z" k="20"/><hkern u1="P" u2="X" k="41"/><hkern u1="P" u2="A" k="102"/><hkern u1="P" u2="." k="266"/><hkern u1="P" u2="," k="266"/><hkern u1="Q" u2="„" k="82"/><hkern u1="Q" u2="‚" k="82"/><hkern u1="Q" u2="Ÿ" k="20"/><hkern u1="Q" u2="Ý" k="20"/><hkern u1="Q" u2="Å" k="41"/><hkern u1="Q" u2="Ä" k="41"/><hkern u1="Q" u2="Ã" k="41"/><hkern u1="Q" u2="Â" k="41"/><hkern u1="Q" u2="Á" k="41"/><hkern u1="Q" u2="À" k="41"/><hkern u1="Q" u2="Z" k="20"/><hkern u1="Q" u2="Y" k="20"/><hkern u1="Q" u2="X" k="41"/><hkern u1="Q" u2="W" k="20"/><hkern u1="Q" u2="V" k="20"/><hkern u1="Q" u2="T" k="61"/><hkern u1="Q" u2="A" k="41"/><hkern u1="Q" u2="." k="82"/><hkern u1="Q" u2="," k="82"/><hkern u1="T" u2="„" k="123"/><hkern u1="T" u2="‚" k="123"/><hkern u1="T" u2="—" k="82"/><hkern u1="T" u2="–" k="82"/><hkern u1="T" u2="œ" k="143"/><hkern u1="T" u2="Œ" k="41"/><hkern u1="T" u2="ý" k="41"/><hkern u1="T" u2="ü" k="102"/><hkern u1="T" u2="û" k="102"/><hkern u1="T" u2="ú" k="102"/><hkern u1="T" u2="ù" k="102"/><hkern u1="T" u2="ø" k="143"/><hkern u1="T" u2="ö" k="143"/><hkern u1="T" u2="õ" k="143"/><hkern u1="T" u2="ô" k="143"/><hkern u1="T" u2="ó" k="143"/><hkern u1="T" u2="ò" k="143"/><hkern u1="T" u2="ë" k="143"/><hkern u1="T" u2="ê" k="143"/><hkern u1="T" u2="é" k="143"/><hkern u1="T" u2="è" k="143"/><hkern u1="T" u2="ç" k="143"/><hkern u1="T" u2="æ" k="164"/><hkern u1="T" u2="å" k="164"/><hkern u1="T" u2="ä" k="164"/><hkern u1="T" u2="ã" k="164"/><hkern u1="T" u2="â" k="164"/><hkern u1="T" u2="á" k="164"/><hkern u1="T" u2="à" k="143"/><hkern u1="T" u2="Ø" k="41"/><hkern u1="T" u2="Ö" k="41"/><hkern u1="T" u2="Õ" k="41"/><hkern u1="T" u2="Ô" k="41"/><hkern u1="T" u2="Ó" k="41"/><hkern u1="T" u2="Ò" k="41"/><hkern u1="T" u2="Ç" k="41"/><hkern u1="T" u2="Å" k="143"/><hkern u1="T" u2="Ä" k="143"/><hkern u1="T" u2="Ã" k="143"/><hkern u1="T" u2="Â" k="143"/><hkern u1="T" u2="Á" k="143"/><hkern u1="T" u2="À" k="143"/><hkern u1="T" u2="z" k="82"/><hkern u1="T" u2="y" k="41"/><hkern u1="T" u2="x" k="41"/><hkern u1="T" u2="w" k="41"/><hkern u1="T" u2="v" k="41"/><hkern u1="T" u2="u" k="102"/><hkern u1="T" u2="s" k="123"/><hkern u1="T" u2="r" k="102"/><hkern u1="T" u2="q" k="143"/><hkern u1="T" u2="p" k="102"/><hkern u1="T" u2="o" k="143"/><hkern u1="T" u2="n" k="102"/><hkern u1="T" u2="m" k="102"/><hkern u1="T" u2="g" k="143"/><hkern u1="T" u2="e" k="143"/><hkern u1="T" u2="d" k="143"/><hkern u1="T" u2="c" k="143"/><hkern u1="T" u2="a" k="164"/><hkern u1="T" u2="T" k="-41"/><hkern u1="T" u2="Q" k="41"/><hkern u1="T" u2="O" k="41"/><hkern u1="T" u2="G" k="41"/><hkern u1="T" u2="C" k="41"/><hkern u1="T" u2="A" k="143"/><hkern u1="T" u2="?" k="-41"/><hkern u1="T" u2="." k="123"/><hkern u1="T" u2="-" k="82"/><hkern u1="T" u2="," k="123"/><hkern u1="U" u2="„" k="41"/><hkern u1="U" u2="‚" k="41"/><hkern u1="U" u2="Å" k="20"/><hkern u1="U" u2="Ä" k="20"/><hkern u1="U" u2="Ã" k="20"/><hkern u1="U" u2="Â" k="20"/><hkern u1="U" u2="Á" k="20"/><hkern u1="U" u2="À" k="20"/><hkern u1="U" u2="A" k="20"/><hkern u1="U" u2="." k="41"/><hkern u1="U" u2="," k="41"/><hkern u1="V" u2="„" k="102"/><hkern u1="V" u2="‚" k="102"/><hkern u1="V" u2="œ" k="41"/><hkern u1="V" u2="Œ" k="20"/><hkern u1="V" u2="ü" k="20"/><hkern u1="V" u2="û" k="20"/><hkern u1="V" u2="ú" k="20"/><hkern u1="V" u2="ù" k="20"/><hkern u1="V" u2="ø" k="41"/><hkern u1="V" u2="ö" k="41"/><hkern u1="V" u2="õ" k="41"/><hkern u1="V" u2="ô" k="41"/><hkern u1="V" u2="ó" k="41"/><hkern u1="V" u2="ò" k="41"/><hkern u1="V" u2="ë" k="41"/><hkern u1="V" u2="ê" k="41"/><hkern u1="V" u2="é" k="41"/><hkern u1="V" u2="è" k="41"/><hkern u1="V" u2="ç" k="41"/><hkern u1="V" u2="æ" k="41"/><hkern u1="V" u2="å" k="41"/><hkern u1="V" u2="ä" k="41"/><hkern u1="V" u2="ã" k="41"/><hkern u1="V" u2="â" k="41"/><hkern u1="V" u2="á" k="41"/><hkern u1="V" u2="à" k="41"/><hkern u1="V" u2="Ø" k="20"/><hkern u1="V" u2="Ö" k="20"/><hkern u1="V" u2="Õ" k="20"/><hkern u1="V" u2="Ô" k="20"/><hkern u1="V" u2="Ó" k="20"/><hkern u1="V" u2="Ò" k="20"/><hkern u1="V" u2="Ç" k="20"/><hkern u1="V" u2="Å" k="82"/><hkern u1="V" u2="Ä" k="82"/><hkern u1="V" u2="Ã" k="82"/><hkern u1="V" u2="Â" k="82"/><hkern u1="V" u2="Á" k="82"/><hkern u1="V" u2="À" k="82"/><hkern u1="V" u2="u" k="20"/><hkern u1="V" u2="s" k="20"/><hkern u1="V" u2="r" k="20"/><hkern u1="V" u2="q" k="41"/><hkern u1="V" u2="p" k="20"/><hkern u1="V" u2="o" k="41"/><hkern u1="V" u2="n" k="20"/><hkern u1="V" u2="m" k="20"/><hkern u1="V" u2="g" k="20"/><hkern u1="V" u2="e" k="41"/><hkern u1="V" u2="d" k="41"/><hkern u1="V" u2="c" k="41"/><hkern u1="V" u2="a" k="41"/><hkern u1="V" u2="Q" k="20"/><hkern u1="V" u2="O" k="20"/><hkern u1="V" u2="G" k="20"/><hkern u1="V" u2="C" k="20"/><hkern u1="V" u2="A" k="82"/><hkern u1="V" u2="?" k="-41"/><hkern u1="V" u2="." k="102"/><hkern u1="V" u2="," k="102"/><hkern u1="W" u2="„" k="102"/><hkern u1="W" u2="‚" k="102"/><hkern u1="W" u2="œ" k="41"/><hkern u1="W" u2="Œ" k="20"/><hkern u1="W" u2="ü" k="20"/><hkern u1="W" u2="û" k="20"/><hkern u1="W" u2="ú" k="20"/><hkern u1="W" u2="ù" k="20"/><hkern u1="W" u2="ø" k="41"/><hkern u1="W" u2="ö" k="41"/><hkern u1="W" u2="õ" k="41"/><hkern u1="W" u2="ô" k="41"/><hkern u1="W" u2="ó" k="41"/><hkern u1="W" u2="ò" k="41"/><hkern u1="W" u2="ë" k="41"/><hkern u1="W" u2="ê" k="41"/><hkern u1="W" u2="é" k="41"/><hkern u1="W" u2="è" k="41"/><hkern u1="W" u2="ç" k="41"/><hkern u1="W" u2="æ" k="41"/><hkern u1="W" u2="å" k="41"/><hkern u1="W" u2="ä" k="41"/><hkern u1="W" u2="ã" k="41"/><hkern u1="W" u2="â" k="41"/><hkern u1="W" u2="á" k="41"/><hkern u1="W" u2="à" k="41"/><hkern u1="W" u2="Ø" k="20"/><hkern u1="W" u2="Ö" k="20"/><hkern u1="W" u2="Õ" k="20"/><hkern u1="W" u2="Ô" k="20"/><hkern u1="W" u2="Ó" k="20"/><hkern u1="W" u2="Ò" k="20"/><hkern u1="W" u2="Ç" k="20"/><hkern u1="W" u2="Å" k="82"/><hkern u1="W" u2="Ä" k="82"/><hkern u1="W" u2="Ã" k="82"/><hkern u1="W" u2="Â" k="82"/><hkern u1="W" u2="Á" k="82"/><hkern u1="W" u2="À" k="82"/><hkern u1="W" u2="u" k="20"/><hkern u1="W" u2="s" k="20"/><hkern u1="W" u2="r" k="20"/><hkern u1="W" u2="q" k="41"/><hkern u1="W" u2="p" k="20"/><hkern u1="W" u2="o" k="41"/><hkern u1="W" u2="n" k="20"/><hkern u1="W" u2="m" k="20"/><hkern u1="W" u2="g" k="20"/><hkern u1="W" u2="e" k="41"/><hkern u1="W" u2="d" k="41"/><hkern u1="W" u2="c" k="41"/><hkern u1="W" u2="a" k="41"/><hkern u1="W" u2="Q" k="20"/><hkern u1="W" u2="O" k="20"/><hkern u1="W" u2="G" k="20"/><hkern u1="W" u2="C" k="20"/><hkern u1="W" u2="A" k="82"/><hkern u1="W" u2="?" k="-41"/><hkern u1="W" u2="." k="102"/><hkern u1="W" u2="," k="102"/><hkern u1="X" u2="Œ" k="41"/><hkern u1="X" u2="Ø" k="41"/><hkern u1="X" u2="Ö" k="41"/><hkern u1="X" u2="Õ" k="41"/><hkern u1="X" u2="Ô" k="41"/><hkern u1="X" u2="Ó" k="41"/><hkern u1="X" u2="Ò" k="41"/><hkern u1="X" u2="Ç" k="41"/><hkern u1="X" u2="Q" k="41"/><hkern u1="X" u2="O" k="41"/><hkern u1="X" u2="G" k="41"/><hkern u1="X" u2="C" k="41"/><hkern u1="Y" u2="„" k="123"/><hkern u1="Y" u2="‚" k="123"/><hkern u1="Y" u2="œ" k="102"/><hkern u1="Y" u2="Œ" k="41"/><hkern u1="Y" u2="ü" k="61"/><hkern u1="Y" u2="û" k="61"/><hkern u1="Y" u2="ú" k="61"/><hkern u1="Y" u2="ù" k="61"/><hkern u1="Y" u2="ø" k="102"/><hkern u1="Y" u2="ö" k="102"/><hkern u1="Y" u2="õ" k="102"/><hkern u1="Y" u2="ô" k="102"/><hkern u1="Y" u2="ó" k="102"/><hkern u1="Y" u2="ò" k="102"/><hkern u1="Y" u2="ë" k="102"/><hkern u1="Y" u2="ê" k="102"/><hkern u1="Y" u2="é" k="102"/><hkern u1="Y" u2="è" k="102"/><hkern u1="Y" u2="ç" k="102"/><hkern u1="Y" u2="æ" k="102"/><hkern u1="Y" u2="å" k="102"/><hkern u1="Y" u2="ä" k="102"/><hkern u1="Y" u2="ã" k="102"/><hkern u1="Y" u2="â" k="102"/><hkern u1="Y" u2="á" k="102"/><hkern u1="Y" u2="à" k="102"/><hkern u1="Y" u2="Ø" k="41"/><hkern u1="Y" u2="Ö" k="41"/><hkern u1="Y" u2="Õ" k="41"/><hkern u1="Y" u2="Ô" k="41"/><hkern u1="Y" u2="Ó" k="41"/><hkern u1="Y" u2="Ò" k="41"/><hkern u1="Y" u2="Ç" k="41"/><hkern u1="Y" u2="Å" k="123"/><hkern u1="Y" u2="Ä" k="123"/><hkern u1="Y" u2="Ã" k="123"/><hkern u1="Y" u2="Â" k="123"/><hkern u1="Y" u2="Á" k="123"/><hkern u1="Y" u2="À" k="123"/><hkern u1="Y" u2="z" k="41"/><hkern u1="Y" u2="u" k="61"/><hkern u1="Y" u2="s" k="82"/><hkern u1="Y" u2="r" k="61"/><hkern u1="Y" u2="q" k="102"/><hkern u1="Y" u2="p" k="61"/><hkern u1="Y" u2="o" k="102"/><hkern u1="Y" u2="n" k="61"/><hkern u1="Y" u2="m" k="61"/><hkern u1="Y" u2="g" k="41"/><hkern u1="Y" u2="e" k="102"/><hkern u1="Y" u2="d" k="102"/><hkern u1="Y" u2="c" k="102"/><hkern u1="Y" u2="a" k="102"/><hkern u1="Y" u2="Q" k="41"/><hkern u1="Y" u2="O" k="41"/><hkern u1="Y" u2="G" k="41"/><hkern u1="Y" u2="C" k="41"/><hkern u1="Y" u2="A" k="123"/><hkern u1="Y" u2="?" k="-41"/><hkern u1="Y" u2="." k="123"/><hkern u1="Y" u2="," k="123"/><hkern u1="Z" u2="Œ" k="20"/><hkern u1="Z" u2="Ø" k="20"/><hkern u1="Z" u2="Ö" k="20"/><hkern u1="Z" u2="Õ" k="20"/><hkern u1="Z" u2="Ô" k="20"/><hkern u1="Z" u2="Ó" k="20"/><hkern u1="Z" u2="Ò" k="20"/><hkern u1="Z" u2="Ç" k="20"/><hkern u1="Z" u2="Q" k="20"/><hkern u1="Z" u2="O" k="20"/><hkern u1="Z" u2="G" k="20"/><hkern u1="Z" u2="C" k="20"/><hkern u1="[" u2="J" k="-184"/><hkern u1="a" u2="”" k="20"/><hkern u1="a" u2="’" k="20"/><hkern u1="a" u2="'" k="20"/><hkern u1="a" u2="&quot;" k="20"/><hkern u1="b" u2="”" k="20"/><hkern u1="b" u2="’" k="20"/><hkern u1="b" u2="ý" k="41"/><hkern u1="b" u2="z" k="20"/><hkern u1="b" u2="y" k="41"/><hkern u1="b" u2="x" k="41"/><hkern u1="b" u2="w" k="41"/><hkern u1="b" u2="v" k="41"/><hkern u1="b" u2="'" k="20"/><hkern u1="b" u2="&quot;" k="20"/><hkern u1="c" u2="”" k="-41"/><hkern u1="c" u2="’" k="-41"/><hkern u1="c" u2="'" k="-41"/><hkern u1="c" u2="&quot;" k="-41"/><hkern u1="e" u2="”" k="20"/><hkern u1="e" u2="’" k="20"/><hkern u1="e" u2="ý" k="41"/><hkern u1="e" u2="z" k="20"/><hkern u1="e" u2="y" k="41"/><hkern u1="e" u2="x" k="41"/><hkern u1="e" u2="w" k="41"/><hkern u1="e" u2="v" k="41"/><hkern u1="e" u2="'" k="20"/><hkern u1="e" u2="&quot;" k="20"/><hkern u1="f" u2="”" k="-123"/><hkern u1="f" u2="’" k="-123"/><hkern u1="f" u2="'" k="-123"/><hkern u1="f" u2="&quot;" k="-123"/><hkern u1="h" u2="”" k="20"/><hkern u1="h" u2="’" k="20"/><hkern u1="h" u2="'" k="20"/><hkern u1="h" u2="&quot;" k="20"/><hkern u1="k" u2="œ" k="41"/><hkern u1="k" u2="ø" k="41"/><hkern u1="k" u2="ö" k="41"/><hkern u1="k" u2="õ" k="41"/><hkern u1="k" u2="ô" k="41"/><hkern u1="k" u2="ó" k="41"/><hkern u1="k" u2="ò" k="41"/><hkern u1="k" u2="ë" k="41"/><hkern u1="k" u2="ê" k="41"/><hkern u1="k" u2="é" k="41"/><hkern u1="k" u2="è" k="41"/><hkern u1="k" u2="ç" k="41"/><hkern u1="k" u2="à" k="41"/><hkern u1="k" u2="q" k="41"/><hkern u1="k" u2="o" k="41"/><hkern u1="k" u2="e" k="41"/><hkern u1="k" u2="d" k="41"/><hkern u1="k" u2="c" k="41"/><hkern u1="m" u2="”" k="20"/><hkern u1="m" u2="’" k="20"/><hkern u1="m" u2="'" k="20"/><hkern u1="m" u2="&quot;" k="20"/><hkern u1="n" u2="”" k="20"/><hkern u1="n" u2="’" k="20"/><hkern u1="n" u2="'" k="20"/><hkern u1="n" u2="&quot;" k="20"/><hkern u1="o" u2="”" k="20"/><hkern u1="o" u2="’" k="20"/><hkern u1="o" u2="ý" k="41"/><hkern u1="o" u2="z" k="20"/><hkern u1="o" u2="y" k="41"/><hkern u1="o" u2="x" k="41"/><hkern u1="o" u2="w" k="41"/><hkern u1="o" u2="v" k="41"/><hkern u1="o" u2="'" k="20"/><hkern u1="o" u2="&quot;" k="20"/><hkern u1="p" u2="”" k="20"/><hkern u1="p" u2="’" k="20"/><hkern u1="p" u2="ý" k="41"/><hkern u1="p" u2="z" k="20"/><hkern u1="p" u2="y" k="41"/><hkern u1="p" u2="x" k="41"/><hkern u1="p" u2="w" k="41"/><hkern u1="p" u2="v" k="41"/><hkern u1="p" u2="'" k="20"/><hkern u1="p" u2="&quot;" k="20"/><hkern u1="r" u2="”" k="-82"/><hkern u1="r" u2="’" k="-82"/><hkern u1="r" u2="œ" k="41"/><hkern u1="r" u2="ø" k="41"/><hkern u1="r" u2="ö" k="41"/><hkern u1="r" u2="õ" k="41"/><hkern u1="r" u2="ô" k="41"/><hkern u1="r" u2="ó" k="41"/><hkern u1="r" u2="ò" k="41"/><hkern u1="r" u2="ë" k="41"/><hkern u1="r" u2="ê" k="41"/><hkern u1="r" u2="é" k="41"/><hkern u1="r" u2="è" k="41"/><hkern u1="r" u2="ç" k="41"/><hkern u1="r" u2="æ" k="41"/><hkern u1="r" u2="å" k="41"/><hkern u1="r" u2="ä" k="41"/><hkern u1="r" u2="ã" k="41"/><hkern u1="r" u2="â" k="41"/><hkern u1="r" u2="á" k="41"/><hkern u1="r" u2="à" k="41"/><hkern u1="r" u2="q" k="41"/><hkern u1="r" u2="o" k="41"/><hkern u1="r" u2="g" k="20"/><hkern u1="r" u2="e" k="41"/><hkern u1="r" u2="d" k="41"/><hkern u1="r" u2="c" k="41"/><hkern u1="r" u2="a" k="41"/><hkern u1="r" u2="'" k="-82"/><hkern u1="r" u2="&quot;" k="-82"/><hkern u1="t" u2="”" k="-41"/><hkern u1="t" u2="’" k="-41"/><hkern u1="t" u2="'" k="-41"/><hkern u1="t" u2="&quot;" k="-41"/><hkern u1="v" u2="„" k="82"/><hkern u1="v" u2="”" k="-82"/><hkern u1="v" u2="‚" k="82"/><hkern u1="v" u2="’" k="-82"/><hkern u1="v" u2="?" k="-41"/><hkern u1="v" u2="." k="82"/><hkern u1="v" u2="," k="82"/><hkern u1="v" u2="'" k="-82"/><hkern u1="v" u2="&quot;" k="-82"/><hkern u1="w" u2="„" k="82"/><hkern u1="w" u2="”" k="-82"/><hkern u1="w" u2="‚" k="82"/><hkern u1="w" u2="’" k="-82"/><hkern u1="w" u2="?" k="-41"/><hkern u1="w" u2="." k="82"/><hkern u1="w" u2="," k="82"/><hkern u1="w" u2="'" k="-82"/><hkern u1="w" u2="&quot;" k="-82"/><hkern u1="x" u2="œ" k="41"/><hkern u1="x" u2="ø" k="41"/><hkern u1="x" u2="ö" k="41"/><hkern u1="x" u2="õ" k="41"/><hkern u1="x" u2="ô" k="41"/><hkern u1="x" u2="ó" k="41"/><hkern u1="x" u2="ò" k="41"/><hkern u1="x" u2="ë" k="41"/><hkern u1="x" u2="ê" k="41"/><hkern u1="x" u2="é" k="41"/><hkern u1="x" u2="è" k="41"/><hkern u1="x" u2="ç" k="41"/><hkern u1="x" u2="à" k="41"/><hkern u1="x" u2="q" k="41"/><hkern u1="x" u2="o" k="41"/><hkern u1="x" u2="e" k="41"/><hkern u1="x" u2="d" k="41"/><hkern u1="x" u2="c" k="41"/><hkern u1="y" u2="„" k="82"/><hkern u1="y" u2="”" k="-82"/><hkern u1="y" u2="‚" k="82"/><hkern u1="y" u2="’" k="-82"/><hkern u1="y" u2="?" k="-41"/><hkern u1="y" u2="." k="82"/><hkern u1="y" u2="," k="82"/><hkern u1="y" u2="'" k="-82"/><hkern u1="y" u2="&quot;" k="-82"/><hkern u1="{" u2="J" k="-184"/><hkern u1="À" u2="”" k="143"/><hkern u1="À" u2="’" k="143"/><hkern u1="À" u2="Ÿ" k="123"/><hkern u1="À" u2="Œ" k="41"/><hkern u1="À" u2="Ý" k="123"/><hkern u1="À" u2="Ø" k="41"/><hkern u1="À" u2="Ö" k="41"/><hkern u1="À" u2="Õ" k="41"/><hkern u1="À" u2="Ô" k="41"/><hkern u1="À" u2="Ó" k="41"/><hkern u1="À" u2="Ò" k="41"/><hkern u1="À" u2="Ç" k="41"/><hkern u1="À" u2="Y" k="123"/><hkern u1="À" u2="W" k="82"/><hkern u1="À" u2="V" k="82"/><hkern u1="À" u2="T" k="143"/><hkern u1="À" u2="Q" k="41"/><hkern u1="À" u2="O" k="41"/><hkern u1="À" u2="J" k="-266"/><hkern u1="À" u2="G" k="41"/><hkern u1="À" u2="C" k="41"/><hkern u1="À" u2="'" k="143"/><hkern u1="À" u2="&quot;" k="143"/><hkern u1="Á" u2="”" k="143"/><hkern u1="Á" u2="’" k="143"/><hkern u1="Á" u2="Ÿ" k="123"/><hkern u1="Á" u2="Œ" k="41"/><hkern u1="Á" u2="Ý" k="123"/><hkern u1="Á" u2="Ø" k="41"/><hkern u1="Á" u2="Ö" k="41"/><hkern u1="Á" u2="Õ" k="41"/><hkern u1="Á" u2="Ô" k="41"/><hkern u1="Á" u2="Ó" k="41"/><hkern u1="Á" u2="Ò" k="41"/><hkern u1="Á" u2="Ç" k="41"/><hkern u1="Á" u2="Y" k="123"/><hkern u1="Á" u2="W" k="82"/><hkern u1="Á" u2="V" k="82"/><hkern u1="Á" u2="T" k="143"/><hkern u1="Á" u2="Q" k="41"/><hkern u1="Á" u2="O" k="41"/><hkern u1="Á" u2="J" k="-266"/><hkern u1="Á" u2="G" k="41"/><hkern u1="Á" u2="C" k="41"/><hkern u1="Á" u2="'" k="143"/><hkern u1="Á" u2="&quot;" k="143"/><hkern u1="Â" u2="”" k="143"/><hkern u1="Â" u2="’" k="143"/><hkern u1="Â" u2="Ÿ" k="123"/><hkern u1="Â" u2="Œ" k="41"/><hkern u1="Â" u2="Ý" k="123"/><hkern u1="Â" u2="Ø" k="41"/><hkern u1="Â" u2="Ö" k="41"/><hkern u1="Â" u2="Õ" k="41"/><hkern u1="Â" u2="Ô" k="41"/><hkern u1="Â" u2="Ó" k="41"/><hkern u1="Â" u2="Ò" k="41"/><hkern u1="Â" u2="Ç" k="41"/><hkern u1="Â" u2="Y" k="123"/><hkern u1="Â" u2="W" k="82"/><hkern u1="Â" u2="V" k="82"/><hkern u1="Â" u2="T" k="143"/><hkern u1="Â" u2="Q" k="41"/><hkern u1="Â" u2="O" k="41"/><hkern u1="Â" u2="J" k="-266"/><hkern u1="Â" u2="G" k="41"/><hkern u1="Â" u2="C" k="41"/><hkern u1="Â" u2="'" k="143"/><hkern u1="Â" u2="&quot;" k="143"/><hkern u1="Ã" u2="”" k="143"/><hkern u1="Ã" u2="’" k="143"/><hkern u1="Ã" u2="Ÿ" k="123"/><hkern u1="Ã" u2="Œ" k="41"/><hkern u1="Ã" u2="Ý" k="123"/><hkern u1="Ã" u2="Ø" k="41"/><hkern u1="Ã" u2="Ö" k="41"/><hkern u1="Ã" u2="Õ" k="41"/><hkern u1="Ã" u2="Ô" k="41"/><hkern u1="Ã" u2="Ó" k="41"/><hkern u1="Ã" u2="Ò" k="41"/><hkern u1="Ã" u2="Ç" k="41"/><hkern u1="Ã" u2="Y" k="123"/><hkern u1="Ã" u2="W" k="82"/><hkern u1="Ã" u2="V" k="82"/><hkern u1="Ã" u2="T" k="143"/><hkern u1="Ã" u2="Q" k="41"/><hkern u1="Ã" u2="O" k="41"/><hkern u1="Ã" u2="J" k="-266"/><hkern u1="Ã" u2="G" k="41"/><hkern u1="Ã" u2="C" k="41"/><hkern u1="Ã" u2="'" k="143"/><hkern u1="Ã" u2="&quot;" k="143"/><hkern u1="Ä" u2="”" k="143"/><hkern u1="Ä" u2="’" k="143"/><hkern u1="Ä" u2="Ÿ" k="123"/><hkern u1="Ä" u2="Œ" k="41"/><hkern u1="Ä" u2="Ý" k="123"/><hkern u1="Ä" u2="Ø" k="41"/><hkern u1="Ä" u2="Ö" k="41"/><hkern u1="Ä" u2="Õ" k="41"/><hkern u1="Ä" u2="Ô" k="41"/><hkern u1="Ä" u2="Ó" k="41"/><hkern u1="Ä" u2="Ò" k="41"/><hkern u1="Ä" u2="Ç" k="41"/><hkern u1="Ä" u2="Y" k="123"/><hkern u1="Ä" u2="W" k="82"/><hkern u1="Ä" u2="V" k="82"/><hkern u1="Ä" u2="T" k="143"/><hkern u1="Ä" u2="Q" k="41"/><hkern u1="Ä" u2="O" k="41"/><hkern u1="Ä" u2="J" k="-266"/><hkern u1="Ä" u2="G" k="41"/><hkern u1="Ä" u2="C" k="41"/><hkern u1="Ä" u2="'" k="143"/><hkern u1="Ä" u2="&quot;" k="143"/><hkern u1="Å" u2="”" k="143"/><hkern u1="Å" u2="’" k="143"/><hkern u1="Å" u2="Ÿ" k="123"/><hkern u1="Å" u2="Œ" k="41"/><hkern u1="Å" u2="Ý" k="123"/><hkern u1="Å" u2="Ø" k="41"/><hkern u1="Å" u2="Ö" k="41"/><hkern u1="Å" u2="Õ" k="41"/><hkern u1="Å" u2="Ô" k="41"/><hkern u1="Å" u2="Ó" k="41"/><hkern u1="Å" u2="Ò" k="41"/><hkern u1="Å" u2="Ç" k="41"/><hkern u1="Å" u2="Y" k="123"/><hkern u1="Å" u2="W" k="82"/><hkern u1="Å" u2="V" k="82"/><hkern u1="Å" u2="T" k="143"/><hkern u1="Å" u2="Q" k="41"/><hkern u1="Å" u2="O" k="41"/><hkern u1="Å" u2="J" k="-266"/><hkern u1="Å" u2="G" k="41"/><hkern u1="Å" u2="C" k="41"/><hkern u1="Å" u2="'" k="143"/><hkern u1="Å" u2="&quot;" k="143"/><hkern u1="Æ" u2="J" k="-123"/><hkern u1="Ç" u2="Œ" k="41"/><hkern u1="Ç" u2="Ø" k="41"/><hkern u1="Ç" u2="Ö" k="41"/><hkern u1="Ç" u2="Õ" k="41"/><hkern u1="Ç" u2="Ô" k="41"/><hkern u1="Ç" u2="Ó" k="41"/><hkern u1="Ç" u2="Ò" k="41"/><hkern u1="Ç" u2="Ç" k="41"/><hkern u1="Ç" u2="Q" k="41"/><hkern u1="Ç" u2="O" k="41"/><hkern u1="Ç" u2="G" k="41"/><hkern u1="Ç" u2="C" k="41"/><hkern u1="È" u2="J" k="-123"/><hkern u1="É" u2="J" k="-123"/><hkern u1="Ê" u2="J" k="-123"/><hkern u1="Ë" u2="J" k="-123"/><hkern u1="Ð" u2="„" k="82"/><hkern u1="Ð" u2="‚" k="82"/><hkern u1="Ð" u2="Ÿ" k="20"/><hkern u1="Ð" u2="Ý" k="20"/><hkern u1="Ð" u2="Å" k="41"/><hkern u1="Ð" u2="Ä" k="41"/><hkern u1="Ð" u2="Ã" k="41"/><hkern u1="Ð" u2="Â" k="41"/><hkern u1="Ð" u2="Á" k="41"/><hkern u1="Ð" u2="À" k="41"/><hkern u1="Ð" u2="Z" k="20"/><hkern u1="Ð" u2="Y" k="20"/><hkern u1="Ð" u2="X" k="41"/><hkern u1="Ð" u2="W" k="20"/><hkern u1="Ð" u2="V" k="20"/><hkern u1="Ð" u2="T" k="61"/><hkern u1="Ð" u2="A" k="41"/><hkern u1="Ð" u2="." k="82"/><hkern u1="Ð" u2="," k="82"/><hkern u1="Ò" u2="„" k="82"/><hkern u1="Ò" u2="‚" k="82"/><hkern u1="Ò" u2="Ÿ" k="20"/><hkern u1="Ò" u2="Ý" k="20"/><hkern u1="Ò" u2="Å" k="41"/><hkern u1="Ò" u2="Ä" k="41"/><hkern u1="Ò" u2="Ã" k="41"/><hkern u1="Ò" u2="Â" k="41"/><hkern u1="Ò" u2="Á" k="41"/><hkern u1="Ò" u2="À" k="41"/><hkern u1="Ò" u2="Z" k="20"/><hkern u1="Ò" u2="Y" k="20"/><hkern u1="Ò" u2="X" k="41"/><hkern u1="Ò" u2="W" k="20"/><hkern u1="Ò" u2="V" k="20"/><hkern u1="Ò" u2="T" k="61"/><hkern u1="Ò" u2="A" k="41"/><hkern u1="Ò" u2="." k="82"/><hkern u1="Ò" u2="," k="82"/><hkern u1="Ó" u2="„" k="82"/><hkern u1="Ó" u2="‚" k="82"/><hkern u1="Ó" u2="Ÿ" k="20"/><hkern u1="Ó" u2="Ý" k="20"/><hkern u1="Ó" u2="Å" k="41"/><hkern u1="Ó" u2="Ä" k="41"/><hkern u1="Ó" u2="Ã" k="41"/><hkern u1="Ó" u2="Â" k="41"/><hkern u1="Ó" u2="Á" k="41"/><hkern u1="Ó" u2="À" k="41"/><hkern u1="Ó" u2="Z" k="20"/><hkern u1="Ó" u2="Y" k="20"/><hkern u1="Ó" u2="X" k="41"/><hkern u1="Ó" u2="W" k="20"/><hkern u1="Ó" u2="V" k="20"/><hkern u1="Ó" u2="T" k="61"/><hkern u1="Ó" u2="A" k="41"/><hkern u1="Ó" u2="." k="82"/><hkern u1="Ó" u2="," k="82"/><hkern u1="Ô" u2="„" k="82"/><hkern u1="Ô" u2="‚" k="82"/><hkern u1="Ô" u2="Ÿ" k="20"/><hkern u1="Ô" u2="Ý" k="20"/><hkern u1="Ô" u2="Å" k="41"/><hkern u1="Ô" u2="Ä" k="41"/><hkern u1="Ô" u2="Ã" k="41"/><hkern u1="Ô" u2="Â" k="41"/><hkern u1="Ô" u2="Á" k="41"/><hkern u1="Ô" u2="À" k="41"/><hkern u1="Ô" u2="Z" k="20"/><hkern u1="Ô" u2="Y" k="20"/><hkern u1="Ô" u2="X" k="41"/><hkern u1="Ô" u2="W" k="20"/><hkern u1="Ô" u2="V" k="20"/><hkern u1="Ô" u2="T" k="61"/><hkern u1="Ô" u2="A" k="41"/><hkern u1="Ô" u2="." k="82"/><hkern u1="Ô" u2="," k="82"/><hkern u1="Õ" u2="„" k="82"/><hkern u1="Õ" u2="‚" k="82"/><hkern u1="Õ" u2="Ÿ" k="20"/><hkern u1="Õ" u2="Ý" k="20"/><hkern u1="Õ" u2="Å" k="41"/><hkern u1="Õ" u2="Ä" k="41"/><hkern u1="Õ" u2="Ã" k="41"/><hkern u1="Õ" u2="Â" k="41"/><hkern u1="Õ" u2="Á" k="41"/><hkern u1="Õ" u2="À" k="41"/><hkern u1="Õ" u2="Z" k="20"/><hkern u1="Õ" u2="Y" k="20"/><hkern u1="Õ" u2="X" k="41"/><hkern u1="Õ" u2="W" k="20"/><hkern u1="Õ" u2="V" k="20"/><hkern u1="Õ" u2="T" k="61"/><hkern u1="Õ" u2="A" k="41"/><hkern u1="Õ" u2="." k="82"/><hkern u1="Õ" u2="," k="82"/><hkern u1="Ö" u2="„" k="82"/><hkern u1="Ö" u2="‚" k="82"/><hkern u1="Ö" u2="Ÿ" k="20"/><hkern u1="Ö" u2="Ý" k="20"/><hkern u1="Ö" u2="Å" k="41"/><hkern u1="Ö" u2="Ä" k="41"/><hkern u1="Ö" u2="Ã" k="41"/><hkern u1="Ö" u2="Â" k="41"/><hkern u1="Ö" u2="Á" k="41"/><hkern u1="Ö" u2="À" k="41"/><hkern u1="Ö" u2="Z" k="20"/><hkern u1="Ö" u2="Y" k="20"/><hkern u1="Ö" u2="X" k="41"/><hkern u1="Ö" u2="W" k="20"/><hkern u1="Ö" u2="V" k="20"/><hkern u1="Ö" u2="T" k="61"/><hkern u1="Ö" u2="A" k="41"/><hkern u1="Ö" u2="." k="82"/><hkern u1="Ö" u2="," k="82"/><hkern u1="Ø" u2="„" k="82"/><hkern u1="Ø" u2="‚" k="82"/><hkern u1="Ø" u2="Ÿ" k="20"/><hkern u1="Ø" u2="Ý" k="20"/><hkern u1="Ø" u2="Å" k="41"/><hkern u1="Ø" u2="Ä" k="41"/><hkern u1="Ø" u2="Ã" k="41"/><hkern u1="Ø" u2="Â" k="41"/><hkern u1="Ø" u2="Á" k="41"/><hkern u1="Ø" u2="À" k="41"/><hkern u1="Ø" u2="Z" k="20"/><hkern u1="Ø" u2="Y" k="20"/><hkern u1="Ø" u2="X" k="41"/><hkern u1="Ø" u2="W" k="20"/><hkern u1="Ø" u2="V" k="20"/><hkern u1="Ø" u2="T" k="61"/><hkern u1="Ø" u2="A" k="41"/><hkern u1="Ø" u2="." k="82"/><hkern u1="Ø" u2="," k="82"/><hkern u1="Ù" u2="„" k="41"/><hkern u1="Ù" u2="‚" k="41"/><hkern u1="Ù" u2="Å" k="20"/><hkern u1="Ù" u2="Ä" k="20"/><hkern u1="Ù" u2="Ã" k="20"/><hkern u1="Ù" u2="Â" k="20"/><hkern u1="Ù" u2="Á" k="20"/><hkern u1="Ù" u2="À" k="20"/><hkern u1="Ù" u2="A" k="20"/><hkern u1="Ù" u2="." k="41"/><hkern u1="Ù" u2="," k="41"/><hkern u1="Ú" u2="„" k="41"/><hkern u1="Ú" u2="‚" k="41"/><hkern u1="Ú" u2="Å" k="20"/><hkern u1="Ú" u2="Ä" k="20"/><hkern u1="Ú" u2="Ã" k="20"/><hkern u1="Ú" u2="Â" k="20"/><hkern u1="Ú" u2="Á" k="20"/><hkern u1="Ú" u2="À" k="20"/><hkern u1="Ú" u2="A" k="20"/><hkern u1="Ú" u2="." k="41"/><hkern u1="Ú" u2="," k="41"/><hkern u1="Û" u2="„" k="41"/><hkern u1="Û" u2="‚" k="41"/><hkern u1="Û" u2="Å" k="20"/><hkern u1="Û" u2="Ä" k="20"/><hkern u1="Û" u2="Ã" k="20"/><hkern u1="Û" u2="Â" k="20"/><hkern u1="Û" u2="Á" k="20"/><hkern u1="Û" u2="À" k="20"/><hkern u1="Û" u2="A" k="20"/><hkern u1="Û" u2="." k="41"/><hkern u1="Û" u2="," k="41"/><hkern u1="Ü" u2="„" k="41"/><hkern u1="Ü" u2="‚" k="41"/><hkern u1="Ü" u2="Å" k="20"/><hkern u1="Ü" u2="Ä" k="20"/><hkern u1="Ü" u2="Ã" k="20"/><hkern u1="Ü" u2="Â" k="20"/><hkern u1="Ü" u2="Á" k="20"/><hkern u1="Ü" u2="À" k="20"/><hkern u1="Ü" u2="A" k="20"/><hkern u1="Ü" u2="." k="41"/><hkern u1="Ü" u2="," k="41"/><hkern u1="Ý" u2="„" k="123"/><hkern u1="Ý" u2="‚" k="123"/><hkern u1="Ý" u2="œ" k="102"/><hkern u1="Ý" u2="Œ" k="41"/><hkern u1="Ý" u2="ü" k="61"/><hkern u1="Ý" u2="û" k="61"/><hkern u1="Ý" u2="ú" k="61"/><hkern u1="Ý" u2="ù" k="61"/><hkern u1="Ý" u2="ø" k="102"/><hkern u1="Ý" u2="ö" k="102"/><hkern u1="Ý" u2="õ" k="102"/><hkern u1="Ý" u2="ô" k="102"/><hkern u1="Ý" u2="ó" k="102"/><hkern u1="Ý" u2="ò" k="102"/><hkern u1="Ý" u2="ë" k="102"/><hkern u1="Ý" u2="ê" k="102"/><hkern u1="Ý" u2="é" k="102"/><hkern u1="Ý" u2="è" k="102"/><hkern u1="Ý" u2="ç" k="102"/><hkern u1="Ý" u2="æ" k="102"/><hkern u1="Ý" u2="å" k="102"/><hkern u1="Ý" u2="ä" k="102"/><hkern u1="Ý" u2="ã" k="102"/><hkern u1="Ý" u2="â" k="102"/><hkern u1="Ý" u2="á" k="102"/><hkern u1="Ý" u2="à" k="102"/><hkern u1="Ý" u2="Ø" k="41"/><hkern u1="Ý" u2="Ö" k="41"/><hkern u1="Ý" u2="Õ" k="41"/><hkern u1="Ý" u2="Ô" k="41"/><hkern u1="Ý" u2="Ó" k="41"/><hkern u1="Ý" u2="Ò" k="41"/><hkern u1="Ý" u2="Ç" k="41"/><hkern u1="Ý" u2="Å" k="123"/><hkern u1="Ý" u2="Ä" k="123"/><hkern u1="Ý" u2="Ã" k="123"/><hkern u1="Ý" u2="Â" k="123"/><hkern u1="Ý" u2="Á" k="123"/><hkern u1="Ý" u2="À" k="123"/><hkern u1="Ý" u2="z" k="41"/><hkern u1="Ý" u2="u" k="61"/><hkern u1="Ý" u2="s" k="82"/><hkern u1="Ý" u2="r" k="61"/><hkern u1="Ý" u2="q" k="102"/><hkern u1="Ý" u2="p" k="61"/><hkern u1="Ý" u2="o" k="102"/><hkern u1="Ý" u2="n" k="61"/><hkern u1="Ý" u2="m" k="61"/><hkern u1="Ý" u2="g" k="41"/><hkern u1="Ý" u2="e" k="102"/><hkern u1="Ý" u2="d" k="102"/><hkern u1="Ý" u2="c" k="102"/><hkern u1="Ý" u2="a" k="102"/><hkern u1="Ý" u2="Q" k="41"/><hkern u1="Ý" u2="O" k="41"/><hkern u1="Ý" u2="G" k="41"/><hkern u1="Ý" u2="C" k="41"/><hkern u1="Ý" u2="A" k="123"/><hkern u1="Ý" u2="?" k="-41"/><hkern u1="Ý" u2="." k="123"/><hkern u1="Ý" u2="," k="123"/><hkern u1="Þ" u2="„" k="266"/><hkern u1="Þ" u2="‚" k="266"/><hkern u1="Þ" u2="Å" k="102"/><hkern u1="Þ" u2="Ä" k="102"/><hkern u1="Þ" u2="Ã" k="102"/><hkern u1="Þ" u2="Â" k="102"/><hkern u1="Þ" u2="Á" k="102"/><hkern u1="Þ" u2="À" k="102"/><hkern u1="Þ" u2="Z" k="20"/><hkern u1="Þ" u2="X" k="41"/><hkern u1="Þ" u2="A" k="102"/><hkern u1="Þ" u2="." k="266"/><hkern u1="Þ" u2="," k="266"/><hkern u1="à" u2="”" k="20"/><hkern u1="à" u2="’" k="20"/><hkern u1="à" u2="'" k="20"/><hkern u1="à" u2="&quot;" k="20"/><hkern u1="á" u2="”" k="20"/><hkern u1="á" u2="’" k="20"/><hkern u1="á" u2="'" k="20"/><hkern u1="á" u2="&quot;" k="20"/><hkern u1="â" u2="”" k="20"/><hkern u1="â" u2="’" k="20"/><hkern u1="â" u2="'" k="20"/><hkern u1="â" u2="&quot;" k="20"/><hkern u1="ã" u2="”" k="20"/><hkern u1="ã" u2="’" k="20"/><hkern u1="ã" u2="'" k="20"/><hkern u1="ã" u2="&quot;" k="20"/><hkern u1="ä" u2="”" k="20"/><hkern u1="ä" u2="’" k="20"/><hkern u1="ä" u2="'" k="20"/><hkern u1="ä" u2="&quot;" k="20"/><hkern u1="å" u2="”" k="20"/><hkern u1="å" u2="’" k="20"/><hkern u1="å" u2="'" k="20"/><hkern u1="å" u2="&quot;" k="20"/><hkern u1="è" u2="”" k="20"/><hkern u1="è" u2="’" k="20"/><hkern u1="è" u2="ý" k="41"/><hkern u1="è" u2="z" k="20"/><hkern u1="è" u2="y" k="41"/><hkern u1="è" u2="x" k="41"/><hkern u1="è" u2="w" k="41"/><hkern u1="è" u2="v" k="41"/><hkern u1="è" u2="'" k="20"/><hkern u1="è" u2="&quot;" k="20"/><hkern u1="é" u2="”" k="20"/><hkern u1="é" u2="’" k="20"/><hkern u1="é" u2="ý" k="41"/><hkern u1="é" u2="z" k="20"/><hkern u1="é" u2="y" k="41"/><hkern u1="é" u2="x" k="41"/><hkern u1="é" u2="w" k="41"/><hkern u1="é" u2="v" k="41"/><hkern u1="é" u2="'" k="20"/><hkern u1="é" u2="&quot;" k="20"/><hkern u1="ê" u2="”" k="20"/><hkern u1="ê" u2="’" k="20"/><hkern u1="ê" u2="ý" k="41"/><hkern u1="ê" u2="z" k="20"/><hkern u1="ê" u2="y" k="41"/><hkern u1="ê" u2="x" k="41"/><hkern u1="ê" u2="w" k="41"/><hkern u1="ê" u2="v" k="41"/><hkern u1="ê" u2="'" k="20"/><hkern u1="ê" u2="&quot;" k="20"/><hkern u1="ë" u2="”" k="20"/><hkern u1="ë" u2="’" k="20"/><hkern u1="ë" u2="ý" k="41"/><hkern u1="ë" u2="z" k="20"/><hkern u1="ë" u2="y" k="41"/><hkern u1="ë" u2="x" k="41"/><hkern u1="ë" u2="w" k="41"/><hkern u1="ë" u2="v" k="41"/><hkern u1="ë" u2="'" k="20"/><hkern u1="ë" u2="&quot;" k="20"/><hkern u1="ð" u2="”" k="20"/><hkern u1="ð" u2="’" k="20"/><hkern u1="ð" u2="ý" k="41"/><hkern u1="ð" u2="z" k="20"/><hkern u1="ð" u2="y" k="41"/><hkern u1="ð" u2="x" k="41"/><hkern u1="ð" u2="w" k="41"/><hkern u1="ð" u2="v" k="41"/><hkern u1="ð" u2="'" k="20"/><hkern u1="ð" u2="&quot;" k="20"/><hkern u1="ò" u2="”" k="20"/><hkern u1="ò" u2="’" k="20"/><hkern u1="ò" u2="ý" k="41"/><hkern u1="ò" u2="z" k="20"/><hkern u1="ò" u2="y" k="41"/><hkern u1="ò" u2="x" k="41"/><hkern u1="ò" u2="w" k="41"/><hkern u1="ò" u2="v" k="41"/><hkern u1="ò" u2="'" k="20"/><hkern u1="ò" u2="&quot;" k="20"/><hkern u1="ó" u2="”" k="20"/><hkern u1="ó" u2="’" k="20"/><hkern u1="ó" u2="ý" k="41"/><hkern u1="ó" u2="z" k="20"/><hkern u1="ó" u2="y" k="41"/><hkern u1="ó" u2="x" k="41"/><hkern u1="ó" u2="w" k="41"/><hkern u1="ó" u2="v" k="41"/><hkern u1="ó" u2="'" k="20"/><hkern u1="ó" u2="&quot;" k="20"/><hkern u1="ô" u2="”" k="20"/><hkern u1="ô" u2="’" k="20"/><hkern u1="ô" u2="ý" k="41"/><hkern u1="ô" u2="z" k="20"/><hkern u1="ô" u2="y" k="41"/><hkern u1="ô" u2="x" k="41"/><hkern u1="ô" u2="w" k="41"/><hkern u1="ô" u2="v" k="41"/><hkern u1="ô" u2="'" k="20"/><hkern u1="ô" u2="&quot;" k="20"/><hkern u1="ö" u2="”" k="41"/><hkern u1="ö" u2="’" k="41"/><hkern u1="ö" u2="'" k="41"/><hkern u1="ö" u2="&quot;" k="41"/><hkern u1="ø" u2="”" k="20"/><hkern u1="ø" u2="’" k="20"/><hkern u1="ø" u2="ý" k="41"/><hkern u1="ø" u2="z" k="20"/><hkern u1="ø" u2="y" k="41"/><hkern u1="ø" u2="x" k="41"/><hkern u1="ø" u2="w" k="41"/><hkern u1="ø" u2="v" k="41"/><hkern u1="ø" u2="'" k="20"/><hkern u1="ø" u2="&quot;" k="20"/><hkern u1="ý" u2="„" k="82"/><hkern u1="ý" u2="”" k="-82"/><hkern u1="ý" u2="‚" k="82"/><hkern u1="ý" u2="’" k="-82"/><hkern u1="ý" u2="?" k="-41"/><hkern u1="ý" u2="." k="82"/><hkern u1="ý" u2="," k="82"/><hkern u1="ý" u2="'" k="-82"/><hkern u1="ý" u2="&quot;" k="-82"/><hkern u1="þ" u2="”" k="20"/><hkern u1="þ" u2="’" k="20"/><hkern u1="þ" u2="ý" k="41"/><hkern u1="þ" u2="z" k="20"/><hkern u1="þ" u2="y" k="41"/><hkern u1="þ" u2="x" k="41"/><hkern u1="þ" u2="w" k="41"/><hkern u1="þ" u2="v" k="41"/><hkern u1="þ" u2="'" k="20"/><hkern u1="þ" u2="&quot;" k="20"/><hkern u1="ÿ" u2="„" k="82"/><hkern u1="ÿ" u2="”" k="-82"/><hkern u1="ÿ" u2="‚" k="82"/><hkern u1="ÿ" u2="’" k="-82"/><hkern u1="ÿ" u2="?" k="-41"/><hkern u1="ÿ" u2="." k="82"/><hkern u1="ÿ" u2="," k="82"/><hkern u1="ÿ" u2="'" k="-82"/><hkern u1="ÿ" u2="&quot;" k="-82"/><hkern u1="Œ" u2="J" k="-123"/><hkern u1="Ÿ" u2="„" k="123"/><hkern u1="Ÿ" u2="‚" k="123"/><hkern u1="Ÿ" u2="œ" k="102"/><hkern u1="Ÿ" u2="Œ" k="41"/><hkern u1="Ÿ" u2="ü" k="61"/><hkern u1="Ÿ" u2="û" k="61"/><hkern u1="Ÿ" u2="ú" k="61"/><hkern u1="Ÿ" u2="ù" k="61"/><hkern u1="Ÿ" u2="ø" k="102"/><hkern u1="Ÿ" u2="ö" k="102"/><hkern u1="Ÿ" u2="õ" k="102"/><hkern u1="Ÿ" u2="ô" k="102"/><hkern u1="Ÿ" u2="ó" k="102"/><hkern u1="Ÿ" u2="ò" k="102"/><hkern u1="Ÿ" u2="ë" k="102"/><hkern u1="Ÿ" u2="ê" k="102"/><hkern u1="Ÿ" u2="é" k="102"/><hkern u1="Ÿ" u2="è" k="102"/><hkern u1="Ÿ" u2="ç" k="102"/><hkern u1="Ÿ" u2="æ" k="102"/><hkern u1="Ÿ" u2="å" k="102"/><hkern u1="Ÿ" u2="ä" k="102"/><hkern u1="Ÿ" u2="ã" k="102"/><hkern u1="Ÿ" u2="â" k="102"/><hkern u1="Ÿ" u2="á" k="102"/><hkern u1="Ÿ" u2="à" k="102"/><hkern u1="Ÿ" u2="Ø" k="41"/><hkern u1="Ÿ" u2="Ö" k="41"/><hkern u1="Ÿ" u2="Õ" k="41"/><hkern u1="Ÿ" u2="Ô" k="41"/><hkern u1="Ÿ" u2="Ó" k="41"/><hkern u1="Ÿ" u2="Ò" k="41"/><hkern u1="Ÿ" u2="Ç" k="41"/><hkern u1="Ÿ" u2="Å" k="123"/><hkern u1="Ÿ" u2="Ä" k="123"/><hkern u1="Ÿ" u2="Ã" k="123"/><hkern u1="Ÿ" u2="Â" k="123"/><hkern u1="Ÿ" u2="Á" k="123"/><hkern u1="Ÿ" u2="À" k="123"/><hkern u1="Ÿ" u2="z" k="41"/><hkern u1="Ÿ" u2="u" k="61"/><hkern u1="Ÿ" u2="s" k="82"/><hkern u1="Ÿ" u2="r" k="61"/><hkern u1="Ÿ" u2="q" k="102"/><hkern u1="Ÿ" u2="p" k="61"/><hkern u1="Ÿ" u2="o" k="102"/><hkern u1="Ÿ" u2="n" k="61"/><hkern u1="Ÿ" u2="m" k="61"/><hkern u1="Ÿ" u2="g" k="41"/><hkern u1="Ÿ" u2="e" k="102"/><hkern u1="Ÿ" u2="d" k="102"/><hkern u1="Ÿ" u2="c" k="102"/><hkern u1="Ÿ" u2="a" k="102"/><hkern u1="Ÿ" u2="Q" k="41"/><hkern u1="Ÿ" u2="O" k="41"/><hkern u1="Ÿ" u2="G" k="41"/><hkern u1="Ÿ" u2="C" k="41"/><hkern u1="Ÿ" u2="A" k="123"/><hkern u1="Ÿ" u2="?" k="-41"/><hkern u1="Ÿ" u2="." k="123"/><hkern u1="Ÿ" u2="," k="123"/><hkern u1="–" u2="T" k="82"/><hkern u1="—" u2="T" k="82"/><hkern u1="‘" u2="Ÿ" k="-20"/><hkern u1="‘" u2="œ" k="123"/><hkern u1="‘" u2="ü" k="61"/><hkern u1="‘" u2="û" k="61"/><hkern u1="‘" u2="ú" k="61"/><hkern u1="‘" u2="ù" k="61"/><hkern u1="‘" u2="ø" k="123"/><hkern u1="‘" u2="ö" k="123"/><hkern u1="‘" u2="õ" k="123"/><hkern u1="‘" u2="ô" k="123"/><hkern u1="‘" u2="ó" k="123"/><hkern u1="‘" u2="ò" k="123"/><hkern u1="‘" u2="ë" k="123"/><hkern u1="‘" u2="ê" k="123"/><hkern u1="‘" u2="é" k="123"/><hkern u1="‘" u2="è" k="123"/><hkern u1="‘" u2="ç" k="123"/><hkern u1="‘" u2="æ" k="82"/><hkern u1="‘" u2="å" k="82"/><hkern u1="‘" u2="ä" k="82"/><hkern u1="‘" u2="ã" k="82"/><hkern u1="‘" u2="â" k="82"/><hkern u1="‘" u2="á" k="82"/><hkern u1="‘" u2="à" k="123"/><hkern u1="‘" u2="Ý" k="-20"/><hkern u1="‘" u2="Å" k="143"/><hkern u1="‘" u2="Ä" k="143"/><hkern u1="‘" u2="Ã" k="143"/><hkern u1="‘" u2="Â" k="143"/><hkern u1="‘" u2="Á" k="143"/><hkern u1="‘" u2="À" k="143"/><hkern u1="‘" u2="u" k="61"/><hkern u1="‘" u2="s" k="61"/><hkern u1="‘" u2="r" k="61"/><hkern u1="‘" u2="q" k="123"/><hkern u1="‘" u2="p" k="61"/><hkern u1="‘" u2="o" k="123"/><hkern u1="‘" u2="n" k="61"/><hkern u1="‘" u2="m" k="61"/><hkern u1="‘" u2="g" k="61"/><hkern u1="‘" u2="e" k="123"/><hkern u1="‘" u2="d" k="123"/><hkern u1="‘" u2="c" k="123"/><hkern u1="‘" u2="a" k="82"/><hkern u1="‘" u2="Y" k="-20"/><hkern u1="‘" u2="W" k="-41"/><hkern u1="‘" u2="V" k="-41"/><hkern u1="‘" u2="T" k="-41"/><hkern u1="‘" u2="A" k="143"/><hkern u1="’" u2="Ÿ" k="-20"/><hkern u1="’" u2="œ" k="123"/><hkern u1="’" u2="ü" k="61"/><hkern u1="’" u2="û" k="61"/><hkern u1="’" u2="ú" k="61"/><hkern u1="’" u2="ù" k="61"/><hkern u1="’" u2="ø" k="123"/><hkern u1="’" u2="ö" k="123"/><hkern u1="’" u2="õ" k="123"/><hkern u1="’" u2="ô" k="123"/><hkern u1="’" u2="ó" k="123"/><hkern u1="’" u2="ò" k="123"/><hkern u1="’" u2="ë" k="123"/><hkern u1="’" u2="ê" k="123"/><hkern u1="’" u2="é" k="123"/><hkern u1="’" u2="è" k="123"/><hkern u1="’" u2="ç" k="123"/><hkern u1="’" u2="æ" k="82"/><hkern u1="’" u2="å" k="82"/><hkern u1="’" u2="ä" k="82"/><hkern u1="’" u2="ã" k="82"/><hkern u1="’" u2="â" k="82"/><hkern u1="’" u2="á" k="82"/><hkern u1="’" u2="à" k="123"/><hkern u1="’" u2="Ý" k="-20"/><hkern u1="’" u2="Å" k="143"/><hkern u1="’" u2="Ä" k="143"/><hkern u1="’" u2="Ã" k="143"/><hkern u1="’" u2="Â" k="143"/><hkern u1="’" u2="Á" k="143"/><hkern u1="’" u2="À" k="143"/><hkern u1="’" u2="u" k="61"/><hkern u1="’" u2="s" k="61"/><hkern u1="’" u2="r" k="61"/><hkern u1="’" u2="q" k="123"/><hkern u1="’" u2="p" k="61"/><hkern u1="’" u2="o" k="123"/><hkern u1="’" u2="n" k="61"/><hkern u1="’" u2="m" k="61"/><hkern u1="’" u2="g" k="61"/><hkern u1="’" u2="e" k="123"/><hkern u1="’" u2="d" k="123"/><hkern u1="’" u2="c" k="123"/><hkern u1="’" u2="a" k="82"/><hkern u1="’" u2="Y" k="-20"/><hkern u1="’" u2="W" k="-41"/><hkern u1="’" u2="V" k="-41"/><hkern u1="’" u2="T" k="-41"/><hkern u1="’" u2="A" k="143"/><hkern u1="‚" u2="Ÿ" k="123"/><hkern u1="‚" u2="Œ" k="102"/><hkern u1="‚" u2="Ý" k="123"/><hkern u1="‚" u2="Ü" k="41"/><hkern u1="‚" u2="Û" k="41"/><hkern u1="‚" u2="Ú" k="41"/><hkern u1="‚" u2="Ù" k="41"/><hkern u1="‚" u2="Ø" k="102"/><hkern u1="‚" u2="Ö" k="102"/><hkern u1="‚" u2="Õ" k="102"/><hkern u1="‚" u2="Ô" k="102"/><hkern u1="‚" u2="Ó" k="102"/><hkern u1="‚" u2="Ò" k="102"/><hkern u1="‚" u2="Ç" k="102"/><hkern u1="‚" u2="Y" k="123"/><hkern u1="‚" u2="W" k="123"/><hkern u1="‚" u2="V" k="123"/><hkern u1="‚" u2="U" k="41"/><hkern u1="‚" u2="T" k="143"/><hkern u1="‚" u2="Q" k="102"/><hkern u1="‚" u2="O" k="102"/><hkern u1="‚" u2="G" k="102"/><hkern u1="‚" u2="C" k="102"/><hkern u1="“" u2="Ÿ" k="-20"/><hkern u1="“" u2="œ" k="123"/><hkern u1="“" u2="ü" k="61"/><hkern u1="“" u2="û" k="61"/><hkern u1="“" u2="ú" k="61"/><hkern u1="“" u2="ù" k="61"/><hkern u1="“" u2="ø" k="123"/><hkern u1="“" u2="ö" k="123"/><hkern u1="“" u2="õ" k="123"/><hkern u1="“" u2="ô" k="123"/><hkern u1="“" u2="ó" k="123"/><hkern u1="“" u2="ò" k="123"/><hkern u1="“" u2="ë" k="123"/><hkern u1="“" u2="ê" k="123"/><hkern u1="“" u2="é" k="123"/><hkern u1="“" u2="è" k="123"/><hkern u1="“" u2="ç" k="123"/><hkern u1="“" u2="æ" k="82"/><hkern u1="“" u2="å" k="82"/><hkern u1="“" u2="ä" k="82"/><hkern u1="“" u2="ã" k="82"/><hkern u1="“" u2="â" k="82"/><hkern u1="“" u2="á" k="82"/><hkern u1="“" u2="à" k="123"/><hkern u1="“" u2="Ý" k="-20"/><hkern u1="“" u2="Å" k="143"/><hkern u1="“" u2="Ä" k="143"/><hkern u1="“" u2="Ã" k="143"/><hkern u1="“" u2="Â" k="143"/><hkern u1="“" u2="Á" k="143"/><hkern u1="“" u2="À" k="143"/><hkern u1="“" u2="u" k="61"/><hkern u1="“" u2="s" k="61"/><hkern u1="“" u2="r" k="61"/><hkern u1="“" u2="q" k="123"/><hkern u1="“" u2="p" k="61"/><hkern u1="“" u2="o" k="123"/><hkern u1="“" u2="n" k="61"/><hkern u1="“" u2="m" k="61"/><hkern u1="“" u2="g" k="61"/><hkern u1="“" u2="e" k="123"/><hkern u1="“" u2="d" k="123"/><hkern u1="“" u2="c" k="123"/><hkern u1="“" u2="a" k="82"/><hkern u1="“" u2="Y" k="-20"/><hkern u1="“" u2="W" k="-41"/><hkern u1="“" u2="V" k="-41"/><hkern u1="“" u2="T" k="-41"/><hkern u1="“" u2="A" k="143"/><hkern u1="„" u2="Ÿ" k="123"/><hkern u1="„" u2="Œ" k="102"/><hkern u1="„" u2="Ý" k="123"/><hkern u1="„" u2="Ü" k="41"/><hkern u1="„" u2="Û" k="41"/><hkern u1="„" u2="Ú" k="41"/><hkern u1="„" u2="Ù" k="41"/><hkern u1="„" u2="Ø" k="102"/><hkern u1="„" u2="Ö" k="102"/><hkern u1="„" u2="Õ" k="102"/><hkern u1="„" u2="Ô" k="102"/><hkern u1="„" u2="Ó" k="102"/><hkern u1="„" u2="Ò" k="102"/><hkern u1="„" u2="Ç" k="102"/><hkern u1="„" u2="Y" k="123"/><hkern u1="„" u2="W" k="123"/><hkern u1="„" u2="V" k="123"/><hkern u1="„" u2="U" k="41"/><hkern u1="„" u2="T" k="143"/><hkern u1="„" u2="Q" k="102"/><hkern u1="„" u2="O" k="102"/><hkern u1="„" u2="G" k="102"/><hkern u1="„" u2="C" k="102"/></font></defs></svg> \ No newline at end of file diff --git a/lib/web/fonts/opensans/light/opensans-300.ttf b/lib/web/fonts/opensans/light/opensans-300.ttf deleted file mode 100644 index 63af664cde6ab..0000000000000 Binary files a/lib/web/fonts/opensans/light/opensans-300.ttf and /dev/null differ diff --git a/lib/web/fonts/opensans/regular/opensans-400.eot b/lib/web/fonts/opensans/regular/opensans-400.eot deleted file mode 100644 index 6bbc3cf58cb01..0000000000000 Binary files a/lib/web/fonts/opensans/regular/opensans-400.eot and /dev/null differ diff --git a/lib/web/fonts/opensans/regular/opensans-400.svg b/lib/web/fonts/opensans/regular/opensans-400.svg deleted file mode 100644 index 3a4a57d6f20a8..0000000000000 --- a/lib/web/fonts/opensans/regular/opensans-400.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg"><defs><font horiz-adv-x="1171"><font-face units-per-em="2048" ascent="1638" descent="-410"/><glyph unicode="fi" horiz-adv-x="1212" d="M29 0zm641 967H391V0H225v967H29v75l196 60v61q0 404 353 404 87 0 204-35l-43-133q-96 31-164 31-94 0-139-62.5T391 1167v-71h279V967zM1036 0H870v1096h166V0zM856 1393q0 57 28 83.5t70 26.5q40 0 69-27t29-83-29-83.5-69-27.5q-42 0-70 27.5t-28 83.5z"/><glyph unicode="fl" horiz-adv-x="1212" d="M29 0zm641 967H391V0H225v967H29v75l196 60v61q0 404 353 404 87 0 204-35l-43-133q-96 31-164 31-94 0-139-62.5T391 1167v-71h279V967zM1036 0H870v1556h166V0z"/><glyph unicode="ffi" horiz-adv-x="1909" d="M29 0zm1329 967h-279V0H913v967H717v75l196 60v61q0 404 353 404 87 0 204-35l-43-133q-96 31-164 31-94 0-139-62.5t-45-200.5v-71h279V967zm-688 0H391V0H225v967H29v75l196 60v61q0 404 353 404 87 0 204-35l-43-133q-96 31-164 31-94 0-139-62.5T391 1167v-71h279V967zM1731 0h-166v1096h166V0zm-180 1393q0 57 28 83.5t70 26.5q40 0 69-27t29-83-29-83.5-69-27.5q-42 0-70 27.5t-28 83.5z"/><glyph unicode="ffl" horiz-adv-x="1909" d="M29 0zm1329 967h-279V0H913v967H717v75l196 60v61q0 404 353 404 87 0 204-35l-43-133q-96 31-164 31-94 0-139-62.5t-45-200.5v-71h279V967zm-688 0H391V0H225v967H29v75l196 60v61q0 404 353 404 87 0 204-35l-43-133q-96 31-164 31-94 0-139-62.5T391 1167v-71h279V967zM1731 0h-166v1556h166V0z"/><glyph horiz-adv-x="2048"/><glyph horiz-adv-x="2048"/><glyph horiz-adv-x="1044"/><glyph horiz-adv-x="532"/><glyph horiz-adv-x="532"/><glyph horiz-adv-x="532"/><glyph unicode="!" horiz-adv-x="547" d="M326 403H221l-51 1059h207zM152 106q0 136 120 136 58 0 89.5-35T393 106q0-64-32-99.5T272-29q-52 0-86 31.5T152 106z"/><glyph unicode="&quot;" horiz-adv-x="821" d="M319 1462l-40-528H174l-41 528h186zm369 0l-41-528H543l-41 528h186z"/><glyph unicode="#" horiz-adv-x="1323" d="M981 899l-66-340h283V430H891L807 0H670l84 430H451L369 0H233l80 430H51v129h287l68 340H129v127h299l82 436h139l-82-436h305l84 436h134l-84-436h264V899H981zM475 559h303l66 340H541z"/><glyph unicode="$" d="M1036 449q0-136-102-224.5T649 113v-232H520v223q-112 0-217 17.5T131 170v156q83-37 191.5-60.5T520 242v440q-205 65-287.5 151T150 1055q0 131 101.5 215T520 1372v182h129v-180q184-5 355-74l-52-131q-149 59-303 70V805q157-50 235-97.5t115-109 37-149.5zm-170-13q0 72-44.5 116.5T649 641V252q217 30 217 184zm-547 621q0-76 45-122t156-87v387q-99-16-150-62.5T319 1057z"/><glyph unicode="%" horiz-adv-x="1686" d="M242 1026q0-170 37-255t120-85q164 0 164 340 0 338-164 338-83 0-120-84t-37-254zm458 0q0-228-76.5-344.5T399 565q-140 0-217.5 119T104 1026q0 227 74.5 342T399 1483q145 0 223-119t78-338zm422-586q0-171 37-255.5t121-84.5 124 83.5 40 256.5q0 171-40 253.5T1280 776t-121-82.5-37-253.5zm459 0q0-227-76.5-343.5T1280-20q-142 0-218.5 119T985 440q0 227 74.5 342T1280 897q142 0 221.5-117.5T1581 440zm-258 1022L512 0H365l811 1462h147z"/><glyph unicode="&" horiz-adv-x="1495" d="M414 1171q0-69 36-131.5T573 889q129 75 179.5 138.5T803 1174q0 77-51.5 125.5T614 1348q-89 0-144.5-48T414 1171zM569 129q241 0 400 154L532 707q-111-68-157-112.5T307 499t-22-116q0-117 77.5-185.5T569 129zM113 379q0 130 69.5 230T432 811q-85 95-115.5 144T268 1057t-18 110q0 150 98 234t273 84q162 0 255-83.5t93-232.5q0-107-68-197.5T676 788l407-391q56 62 89.5 145.5T1229 725h168q-68-286-205-434L1491 0h-229l-185 178Q959 72 837 26T565-20Q350-20 231.5 86T113 379z"/><glyph unicode="'" horiz-adv-x="453" d="M319 1462l-40-528H174l-41 528h186z"/><glyph unicode="(" horiz-adv-x="606" d="M82 561q0 265 77.5 496T383 1462h162q-144-193-216.5-424T256 563q0-240 74-469t213-418H383Q236-154 159 73T82 561z"/><glyph unicode=")" horiz-adv-x="606" d="M524 561q0-263-77.5-490T223-324H63Q202-136 276 93.5T350 563q0 244-72.5 475T61 1462h162q147-175 224-406.5T524 561z"/><glyph unicode="*" horiz-adv-x="1130" d="M657 1556l-43-395 398 111 26-182-381-31 248-326-172-94-176 362-160-362-176 94 242 326-377 31 29 182 391-111-43 395h194z"/><glyph unicode="+" d="M653 791h412V653H653V227H514v426H104v138h410v428h139V791z"/><glyph unicode="," horiz-adv-x="502" d="M350 238l15-23q-26-100-75-232.5T188-264H63Q90-160 122.5-7T168 238h182z"/><glyph unicode="-" horiz-adv-x="659" d="M84 473v152h491V473H84z"/><glyph unicode="." horiz-adv-x="545" d="M152 106q0 67 30.5 101.5T270 242q58 0 90.5-34.5T393 106q0-65-33-100t-90-35q-51 0-84.5 31.5T152 106z"/><glyph unicode="/" horiz-adv-x="752" d="M731 1462L186 0H20l545 1462h166z"/><glyph unicode="0" d="M1069 733q0-379-119.5-566T584-20q-236 0-359 191.5T102 733q0 382 119 567t363 185q238 0 361.5-193T1069 733zm-799 0q0-319 75-464.5T584 123q166 0 240.5 147.5T899 733t-74.5 461.5T584 1341q-164 0-239-144.5T270 733z"/><glyph unicode="1" d="M715 0H553v1042q0 130 8 246-21-21-47-44t-238-195l-88 114 387 299h140V0z"/><glyph unicode="2" d="M1061 0H100v143l385 387q176 178 232 254t84 148 28 155q0 117-71 185.5T561 1341q-91 0-172.5-30T207 1202l-88 113q202 168 440 168 206 0 323-105.5T999 1094q0-139-78-275T629 475L309 162v-8h752V0z"/><glyph unicode="3" d="M1006 1118q0-140-78.5-229T705 770v-8q176-22 261-112t85-236q0-209-145-321.5T494-20Q378-20 281.5-2.5T94 59v158q95-47 202.5-71.5T500 121q379 0 379 297 0 266-418 266H317v143h146q171 0 271 75.5T834 1112q0 107-73.5 168T561 1341q-96 0-181-26t-194-96l-84 112q90 71 207.5 111.5T557 1483q213 0 331-97.5t118-267.5z"/><glyph unicode="4" d="M1130 336H913V0H754v336H43v145l694 989h176V487h217V336zM754 487v486q0 143 10 323h-8q-48-96-90-159L209 487h545z"/><glyph unicode="5" d="M557 893q231 0 363.5-114.5T1053 465q0-227-144.5-356T510-20q-247 0-377 79v160q70-45 174-70.5T512 123q176 0 273.5 83T883 446q0 306-375 306-95 0-254-29l-86 55 55 684h727v-153H365l-37-439q115 23 229 23z"/><glyph unicode="6" d="M117 625q0 431 167.5 644.5T780 1483q113 0 178-19v-143q-77 25-176 25-235 0-359-146.5T287 739h12q110 172 348 172 197 0 310.5-119T1071 469q0-228-124.5-358.5T610-20q-227 0-360 170.5T117 625zm491-504q142 0 220.5 89.5T907 469q0 145-73 228t-218 83q-90 0-165-37T331.5 641 287 506q0-103 40-192t113.5-141T608 121z"/><glyph unicode="7" d="M285 0l606 1309H94v153h973v-133L469 0H285z"/><glyph unicode="8" d="M584 1483q200 0 317-93t117-257q0-108-67-197T737 774q178-85 253-178.5t75-216.5q0-182-127-290.5T590-20Q356-20 230 82.5T104 373q0 251 306 391-138 78-198 168.5T152 1135q0 159 117.5 253.5T584 1483zM268 369q0-120 83.5-187T586 115q149 0 232 70t83 192q0 97-78 172.5T551 696q-149-64-216-141.5T268 369zm314 979q-125 0-196-60t-71-160q0-92 59-158t218-132q143 60 202.5 129t59.5 161q0 101-72.5 160.5T582 1348z"/><glyph unicode="9" d="M1061 838q0-858-664-858-116 0-184 20v143q80-26 182-26 240 0 362.5 148.5T891 721h-12q-55-83-146-126.5T528 551q-194 0-308 116T106 991q0 228 127.5 360T569 1483q149 0 260.5-76.5t171.5-223 60-345.5zm-492 503q-143 0-221-92t-78-256q0-144 72-226.5T561 684q91 0 167.5 37T849 822t44 134q0 105-41 194t-114.5 140-168.5 51z"/><glyph unicode=":" horiz-adv-x="545" d="M152 106q0 67 30.5 101.5T270 242q58 0 90.5-34.5T393 106q0-65-33-100t-90-35q-51 0-84.5 31.5T152 106zm0 883q0 135 118 135 123 0 123-135 0-65-33-100t-90-35q-51 0-84.5 31.5T152 989z"/><glyph unicode=";" horiz-adv-x="545" d="M350 238l15-23q-26-100-75-232.5T188-264H63Q90-160 122.5-7T168 238h182zM147 989q0 135 119 135 123 0 123-135 0-65-33-100t-90-35q-58 0-88.5 35T147 989z"/><glyph unicode="<" d="M1065 242L104 664v98l961 479v-149L283 721l782-328V242z"/><glyph unicode="=" d="M119 858v137h930V858H119zm0-409v137h930V449H119z"/><glyph unicode=">" d="M104 393l783 326-783 373v149l961-479v-98L104 242v151z"/><glyph unicode="?" horiz-adv-x="879" d="M289 403v54q0 117 36 192.5T459 809q136 115 171.5 173t35.5 140q0 102-65.5 157.5T412 1335q-79 0-154-18.5T86 1249l-59 135q189 99 395 99 191 0 297-94t106-265q0-73-19.5-128.5t-57.5-105T584 731q-101-86-133.5-143T418 436v-33H289zm-49-297q0 136 120 136 58 0 89.5-35T481 106q0-64-32-99.5T360-29q-52 0-86 31.5T240 106z"/><glyph unicode="@" horiz-adv-x="1841" d="M1720 729q0-142-44-260t-124-183-184-65q-86 0-145 52t-70 133h-8q-40-87-114.5-136T854 221q-150 0-234.5 102.5T535 602q0 204 118 331.5T963 1061q68 0 154-12.5t155-34.5l-25-470v-22q0-178 133-178 91 0 148 107.5t57 279.5q0 181-74 317t-210.5 209.5T987 1331q-223 0-388-92.5t-252-264T260 578q0-305 161-469T885-55q210 0 436 86v-133q-192-84-436-84-363 0-563.5 199.5T121 571q0 260 107 463t305 314.5T987 1460q215 0 382.5-90.5t259-257T1720 729zM686 598q0-254 195-254 207 0 225 313l14 261q-72 20-157 20-130 0-203.5-90T686 598z"/><glyph unicode="A" horiz-adv-x="1296" d="M1120 0L938 465H352L172 0H0l578 1468h143L1296 0h-176zM885 618l-170 453q-33 86-68 211-22-96-63-211L412 618h473z"/><glyph unicode="B" horiz-adv-x="1327" d="M201 1462h413q291 0 421-87t130-275q0-130-72.5-214.5T881 776v-10q333-57 333-350 0-196-132.5-306T711 0H201v1462zm170-626h280q180 0 259 56.5t79 190.5q0 123-88 177.5T621 1315H371V836zm0-144V145h305q177 0 266.5 68.5T1032 428q0 136-91.5 200T662 692H371z"/><glyph unicode="C" horiz-adv-x="1292" d="M827 1331q-241 0-380.5-160.5T307 731q0-287 134.5-443.5T825 131q153 0 349 55V37q-152-57-375-57-323 0-498.5 196T125 733q0 226 84.5 396t244 262 375.5 92q230 0 402-84l-72-146q-166 78-332 78z"/><glyph unicode="D" horiz-adv-x="1493" d="M1368 745q0-362-196.5-553.5T606 0H201v1462h448q341 0 530-189t189-528zm-180-6q0 286-143.5 431T618 1315H371V147h207q304 0 457 149.5T1188 739z"/><glyph unicode="E" horiz-adv-x="1139" d="M1016 0H201v1462h815v-151H371V840h606V690H371V152h645V0z"/><glyph unicode="F" horiz-adv-x="1057" d="M371 0H201v1462h815v-151H371V776h606V625H371V0z"/><glyph unicode="G" horiz-adv-x="1491" d="M844 766h497V55q-116-37-236-56T827-20q-332 0-517 197.5T125 731q0 228 91.5 399.5t263.5 262 403 90.5q234 0 436-86l-66-150q-198 84-381 84-267 0-417-159T305 731q0-296 144.5-449T874 129q152 0 297 35v450H844v152z"/><glyph unicode="H" horiz-adv-x="1511" d="M1311 0h-170v688H371V0H201v1462h170V840h770v622h170V0z"/><glyph unicode="I" horiz-adv-x="571" d="M201 0v1462h170V0H201z"/><glyph unicode="J" horiz-adv-x="547" d="M-12-385q-94 0-148 27v145q71-20 148-20 99 0 150.5 60T190 0v1462h170V14q0-190-96-294.5T-12-385z"/><glyph unicode="K" horiz-adv-x="1257" d="M1257 0h-200L524 709 371 573V0H201v1462h170V737l663 725h201L647 827z"/><glyph unicode="L" horiz-adv-x="1063" d="M201 0v1462h170V154h645V0H201z"/><glyph unicode="M" horiz-adv-x="1849" d="M848 0L352 1296h-8q14-154 14-366V0H201v1462h256L920 256h8l467 1206h254V0h-170v942q0 162 14 352h-8L985 0H848z"/><glyph unicode="N" horiz-adv-x="1544" d="M1343 0h-194L350 1227h-8q16-216 16-396V0H201v1462h192l797-1222h8q-2 27-9 173.5t-5 209.5v839h159V0z"/><glyph unicode="O" horiz-adv-x="1595" d="M1470 733q0-351-177.5-552T799-20q-323 0-498.5 197.5T125 735q0 357 176 553.5T801 1485q315 0 492-200t177-552zm-1165 0q0-297 126.5-450.5T799 129q243 0 367 153t124 451q0 295-123.5 447.5T801 1333q-243 0-369.5-153.5T305 733z"/><glyph unicode="P" horiz-adv-x="1233" d="M1128 1036q0-222-151.5-341.5T543 575H371V0H201v1462h379q548 0 548-426zM371 721h153q226 0 327 73t101 234q0 145-95 216t-296 71H371V721z"/><glyph unicode="Q" horiz-adv-x="1595" d="M1470 733q0-281-113-467T1038 14l348-362h-247L854-18l-55-2q-323 0-498.5 197.5T125 735q0 357 176 553.5T801 1485q315 0 492-200t177-552zm-1165 0q0-297 126.5-450.5T799 129q243 0 367 153t124 451q0 295-123.5 447.5T801 1333q-243 0-369.5-153.5T305 733z"/><glyph unicode="R" horiz-adv-x="1266" d="M371 608V0H201v1462h401q269 0 397.5-103t128.5-310q0-290-294-392L1231 0h-201L676 608H371zm0 146h233q180 0 264 71.5t84 214.5q0 145-85.5 209T592 1313H371V754z"/><glyph unicode="S" horiz-adv-x="1124" d="M1026 389q0-193-140-301T506-20q-260 0-400 67v164q90-38 196-60t210-22q170 0 256 64.5T854 373q0 76-30.5 124.5t-102 89.5T504 680q-204 73-291.5 173T125 1114q0 169 127 269t336 100q218 0 401-80l-53-148q-181 76-352 76-135 0-211-58t-76-161q0-76 28-124.5t94.5-89T623 809q230-82 316.5-176t86.5-244z"/><glyph unicode="T" horiz-adv-x="1133" d="M651 0H481v1311H18v151h1096v-151H651V0z"/><glyph unicode="U" horiz-adv-x="1491" d="M1305 1462V516q0-250-151-393T739-20 330.5 124 186 520v942h170V508q0-183 100-281t294-98q185 0 285 98.5T1135 510v952h170z"/><glyph unicode="V" horiz-adv-x="1219" d="M1036 1462h183L692 0H524L0 1462h180l336-946q58-163 92-317 36 162 94 323z"/><glyph unicode="W" horiz-adv-x="1896" d="M1477 0h-168l-295 979q-21 65-47 164t-27 119q-22-132-70-289L584 0H416L27 1462h180l231-903q48-190 70-344 27 183 80 358l262 889h180l275-897q48-155 81-350 19 142 72 346l230 901h180z"/><glyph unicode="X" horiz-adv-x="1182" d="M1174 0H981L588 643 188 0H8l486 764-453 698h188l363-579 366 579h181L686 770z"/><glyph unicode="Y" horiz-adv-x="1147" d="M573 731l390 731h184L659 567V0H487v559L0 1462h186z"/><glyph unicode="Z" horiz-adv-x="1169" d="M1087 0H82v133l776 1176H106v153h959v-133L289 154h798V0z"/><glyph unicode="[" horiz-adv-x="674" d="M623-324H166v1786h457v-141H334V-182h289v-142z"/><glyph unicode="\" horiz-adv-x="752" d="M186 1462L733 0H567L23 1462h163z"/><glyph unicode="]" horiz-adv-x="674" d="M51-182h289v1503H51v141h457V-324H51v142z"/><glyph unicode="^" horiz-adv-x="1110" d="M49 551l434 922h99l477-922H907l-372 745-334-745H49z"/><glyph unicode="_" horiz-adv-x="918" d="M922-315H-4v131h926v-131z"/><glyph unicode="`" horiz-adv-x="1182" d="M786 1241H676q-65 52-154 148t-129 159v21h203q32-69 89-159.5T786 1266v-25z"/><glyph unicode="a" horiz-adv-x="1139" d="M850 0l-33 156h-8Q727 53 645.5 16.5T442-20q-163 0-255.5 84T94 303q0 332 531 348l186 6v68q0 129-55.5 190.5T578 977q-137 0-310-84l-51 127q81 44 177.5 69t193.5 25q196 0 290.5-87T973 748V0H850zM475 117q155 0 243.5 85T807 440v99l-166-7q-198-7-285.5-61.5T268 301q0-90 54.5-137T475 117z"/><glyph unicode="b" horiz-adv-x="1255" d="M686 1114q216 0 335.5-147.5T1141 549t-120.5-419.5T686-20q-107 0-195.5 39.5T342 141h-12L295 0H176v1556h166v-378q0-127-8-228h8q116 164 344 164zm-24-139q-170 0-245-97.5T342 549t77-330.5T666 119q153 0 228 111.5T969 551q0 214-75 319T662 975z"/><glyph unicode="c" horiz-adv-x="975" d="M614-20q-238 0-368.5 146.5T115 541q0 275 132.5 425T625 1116q79 0 158-17t124-40l-51-141q-55 22-120 36.5T621 969q-334 0-334-426 0-202 81.5-310T610 125q137 0 281 59V37Q781-20 614-20z"/><glyph unicode="d" horiz-adv-x="1255" d="M922 147h-9Q798-20 569-20q-215 0-334.5 147T115 545t120 421 334 150q223 0 342-162h13l-7 79-4 77v446h166V0H944zm-332-28q170 0 246.5 92.5T913 510v35q0 233-77.5 332.5T588 977q-146 0-223.5-113.5T287 543q0-210 77-317t226-107z"/><glyph unicode="e" horiz-adv-x="1149" d="M639-20q-243 0-383.5 148T115 539q0 265 130.5 421T596 1116q206 0 326-135.5T1042 623V518H287q5-193 97.5-293T645 125q177 0 350 74V51Q907 13 828.5-3.5T639-20zm-45 997q-132 0-210.5-86T291 653h573q0 157-70 240.5T594 977z"/><glyph unicode="f" horiz-adv-x="694" d="M670 967H391V0H225v967H29v75l196 60v61q0 404 353 404 87 0 204-35l-43-133q-96 31-164 31-94 0-139-62.5T391 1167v-71h279V967z"/><glyph unicode="g" horiz-adv-x="1122" d="M1073 1096V991l-203-24q28-35 50-91.5T942 748q0-161-110-257t-302-96q-49 0-92 8-106-56-106-141 0-45 37-66.5T496 174h194q178 0 273.5-75t95.5-218q0-182-146-277.5T487-492q-215 0-331.5 80T39-186q0 100 64 173t180 99q-42 19-70.5 59T184 238q0 60 32 105t101 87q-85 35-138.5 119T125 741q0 180 108 277.5t306 97.5q86 0 155-20h379zM199-184q0-89 75-135t215-46q209 0 309.5 62.5T899-133q0 89-55 123.5T637 25H438q-113 0-176-54t-63-155zm90 929q0-115 65-174t181-59q243 0 243 236 0 247-246 247-117 0-180-63t-63-187z"/><glyph unicode="h" horiz-adv-x="1257" d="M926 0v709q0 134-61 200t-191 66q-173 0-252.5-94T342 573V0H176v1556h166v-471q0-85-8-141h10q49 79 139.5 124.5T690 1114q201 0 301.5-95.5T1092 715V0H926z"/><glyph unicode="i" horiz-adv-x="518" d="M342 0H176v1096h166V0zM162 1393q0 57 28 83.5t70 26.5q40 0 69-27t29-83-29-83.5-69-27.5q-42 0-70 27.5t-28 83.5z"/><glyph unicode="j" horiz-adv-x="518" d="M43-492q-95 0-154 25v135q69-20 136-20 78 0 114.5 42.5T176-180v1276h166V-168q0-324-299-324zm119 1885q0 57 28 83.5t70 26.5q40 0 69-27t29-83-29-83.5-69-27.5q-42 0-70 27.5t-28 83.5z"/><glyph unicode="k" horiz-adv-x="1075" d="M340 561q43 61 131 160l354 375h197L578 629 1053 0H852L465 518 340 410V0H176v1556h164V731q0-55-8-170h8z"/><glyph unicode="l" horiz-adv-x="518" d="M342 0H176v1556h166V0z"/><glyph unicode="m" horiz-adv-x="1905" d="M1573 0v713q0 131-56 196.5T1343 975q-155 0-229-89t-74-274V0H874v713q0 131-56 196.5T643 975q-156 0-228.5-93.5T342 575V0H176v1096h135l27-150h8q47 80 132.5 125t191.5 45q257 0 336-186h8q49 86 142 136t212 50q186 0 278.5-95.5T1739 715V0h-166z"/><glyph unicode="n" horiz-adv-x="1257" d="M926 0v709q0 134-61 200t-191 66q-172 0-252-93t-80-307V0H176v1096h135l27-150h8q51 81 143 125.5t205 44.5q198 0 298-95.5T1092 715V0H926z"/><glyph unicode="o" horiz-adv-x="1237" d="M1122 549q0-268-135-418.5T614-20q-147 0-261 69T177 247t-62 302q0 268 134 417.5T621 1116q230 0 365.5-153T1122 549zm-835 0q0-210 84-320t247-110 247.5 109.5T950 549q0 209-84.5 317.5T616 975q-163 0-246-107t-83-319z"/><glyph unicode="p" horiz-adv-x="1255" d="M686-20q-107 0-195.5 39.5T342 141h-12q12-96 12-182v-451H176v1588h135l23-150h8q64 90 149 130t195 40q218 0 336.5-149T1141 549q0-270-120.5-419.5T686-20zm-24 995q-168 0-243-93t-77-296v-37q0-231 77-330.5T666 119q142 0 222.5 115T969 551q0 205-80.5 314.5T662 975z"/><glyph unicode="q" horiz-adv-x="1255" d="M590 119q166 0 242 89t81 300v37q0 230-78 331T588 977q-146 0-223.5-113.5T287 543t76.5-315.5T590 119zM565-20q-212 0-331 149T115 545q0 269 120 420t334 151q225 0 346-170h9l24 150h131V-492H913v469q0 100 11 170h-13Q796-20 565-20z"/><glyph unicode="r" horiz-adv-x="836" d="M676 1116q73 0 131-12l-23-154q-68 15-120 15-133 0-227.5-108T342 588V0H176v1096h137l19-203h8q61 107 147 165t189 58z"/><glyph unicode="s" horiz-adv-x="977" d="M883 299q0-153-114-236T449-20q-218 0-340 69v154q79-40 169.5-63T453 117q130 0 200 41.5T723 285q0 64-55.5 109.5T451 502q-153 57-217.5 99.5t-96 96.5T106 827q0 134 109 211.5t299 77.5q177 0 346-72l-59-135q-165 68-299 68-118 0-178-37t-60-102q0-44 22.5-75t72.5-59 192-81q195-71 263.5-143T883 299z"/><glyph unicode="t" horiz-adv-x="723" d="M530 117q44 0 85 6.5t65 13.5V10q-27-13-79.5-21.5T506-20q-318 0-318 335v652H31v80l157 69 70 234h96v-254h318V967H354V322q0-99 47-152t129-53z"/><glyph unicode="u" horiz-adv-x="1257" d="M332 1096V385q0-134 61-200t191-66q172 0 251.5 94T915 520v576h166V0H944l-24 147h-9Q860 66 769.5 23T563-20q-200 0-299.5 95T164 379v717h168z"/><glyph unicode="v" horiz-adv-x="1026" d="M416 0L0 1096h178l236-650q80-228 94-296h8q11 53 69.5 219.5T848 1096h178L610 0H416z"/><glyph unicode="w" horiz-adv-x="1593" d="M1071 0L870 643q-19 59-71 268h-8q-40-175-70-270L514 0H322L23 1096h174q106-413 161.5-629T422 176h8q11 57 35.5 147.5T508 467l201 629h180l196-629q56-172 76-289h8q4 36 21.5 111t208.5 807h172L1268 0h-197z"/><glyph unicode="x" horiz-adv-x="1073" d="M440 561L59 1096h189l289-420 288 420h187L631 561 1032 0H844L537 444 227 0H39z"/><glyph unicode="y" horiz-adv-x="1032" d="M2 1096h178l240-625q79-214 98-309h8q13 51 54.5 174.5T852 1096h178L559-152q-70-185-163.5-262.5T166-492q-76 0-150 17v133q55-12 123-12 171 0 244 192L444-6z"/><glyph unicode="z" horiz-adv-x="958" d="M877 0H82v113l598 854H119v129h743V967L272 129h605V0z"/><glyph unicode="{" horiz-adv-x="776" d="M475 12q0-102 58.5-148T705-184v-140q-190 2-294 87T307 2v303q0 104-63 148.5T61 498v141q130 2 188 48t58 142v306q0 155 108 241t290 86v-139q-230-6-230-199V829q0-215-223-254v-12q223-39 223-254V12z"/><glyph unicode="|" horiz-adv-x="1128" d="M494 1556h141V-496H494v2052z"/><glyph unicode="}" horiz-adv-x="776" d="M522 575q-223 39-223 254v295q0 193-227 199v139q184 0 289.5-87T467 1135V829q0-97 59-142.5T715 639V498q-122 0-185-44.5T467 305V2q0-153-102.5-238.5T72-324v140q111 2 169 48t58 148v297q0 114 55 174t168 80v12z"/><glyph unicode="~" d="M338 713q-53 0-116.5-33.5T104 592v151q100 109 244 109 68 0 124.5-14T618 786q66-28 115-41.5t96-13.5q54 0 118 32t118 89V702Q963 592 821 592q-72 0-135 16.5T551 657q-75 32-120 44t-93 12z"/><glyph unicode="¡" horiz-adv-x="547" d="M219 684h105l51-1057H168zm174 299q0-135-121-135-60 0-90 35.5T152 983q0 63 31.5 99t88.5 36q51 0 86-32t35-103z"/><glyph unicode="¢" d="M971 240q-105-54-252-60V-20H586v206q-203 32-299.5 168.5T190 741q0 508 396 570v172h135v-164q75-3 146-19.5t120-39.5l-49-140q-133 51-242 51-172 0-253-105.5T362 743q0-212 79.5-313.5T688 328q141 0 283 59V240z"/><glyph unicode="£" d="M682 1481q190 0 360-84l-61-133q-154 77-297 77-123 0-185.5-62T436 1077V782h422V655H436V434q0-100-32.5-168T297 154h795V0H63v141q205 47 205 291v223H70v127h198v316q0 178 112 280.5T682 1481z"/><glyph unicode="¤" d="M184 723q0 122 74 229l-135 140 94 92 135-133q104 73 234 73 127 0 229-73l137 133 95-92-134-138q74-113 74-231 0-131-74-234l131-135-92-92-137 133q-102-71-229-71-134 0-234 73L217 264l-92 92 133 136q-74 107-74 231zm129 0q0-112 78.5-192T586 451t195 79.5T860 723q0 114-80 195t-194 81q-116 0-194.5-82T313 723z"/><glyph unicode="¥" d="M584 735l379 727h174L721 692h262V565H666V395h317V268H666V0H502v268H186v127h316v170H186v127h256L31 1462h178z"/><glyph unicode="¦" horiz-adv-x="1128" d="M494 1556h141V780H494v776zm0-1275h141v-777H494v777z"/><glyph unicode="§" horiz-adv-x="1057" d="M139 809q0 86 43 154.5T303 1069q-74 40-116 95.5T145 1305q0 121 103.5 190.5T549 1565q94 0 173.5-14.5T899 1497l-53-131q-98 39-165.5 52.5T537 1432q-116 0-174-29.5t-58-93.5q0-60 61.5-102t215.5-97q186-68 261-143.5T918 784q0-90-41-160.5T762 512q153-81 153-227 0-140-117-216.5T469-8Q251-8 123 57v148q78-37 175-59.5T477 123q134 0 204.5 38T752 270q0 46-24 75t-78 58-169 72q-142 52-209 97T172 674t-33 135zm146 20q0-77 66-129.5T584 586l49-19q137 80 137 191 0 83-73.5 139T438 1010q-68-19-110.5-69T285 829z"/><glyph unicode="¨" horiz-adv-x="1182" d="M309 1393q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T399 1294q-37 0-63.5 24.5T309 1393zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T780 1294t-63.5 24.5T690 1393z"/><glyph unicode="©" horiz-adv-x="1704" d="M893 1059q-125 0-192.5-87T633 731q0-168 63.5-249T891 401q86 0 211 45V322q-48-20-98.5-34T883 274q-194 0-298 120.5T481 731q0 209 110.5 332T893 1186q128 0 246-60l-58-118q-108 51-188 51zM100 731q0 200 100 375t275 276 377 101q200 0 375-100t276-275 101-377q0-197-97-370T1235 84 852-20Q645-20 470 83.5T197.5 360 100 731zm105 0q0-173 87-323.5t237.5-237T852 84q174 0 323 87t236.5 235.5T1499 731q0 174-87 323t-235.5 236.5T852 1378q-174 0-323-87t-236.5-235.5T205 731z"/><glyph unicode="ª" horiz-adv-x="725" d="M532 801l-24 84q-92-97-232-97-95 0-150.5 49.5T70 989t77 154.5 242 58.5l117 4v39q0 133-148 133-100 0-204-51l-43 96q114 56 247 56 130 0 198.5-52.5T625 1253V801h-93zM193 989q0-100 112-100 201 0 201 180v49l-98-4q-112-4-163.5-32.5T193 989z"/><glyph unicode="«" horiz-adv-x="1018" d="M82 551l342 407 119-69-289-350 289-351-119-71L82 524v27zm395 0l344 407 117-69-287-350 287-351-117-71-344 407v27z"/><glyph unicode="¬" d="M1065 791V264H928v389H104v138h961z"/><glyph unicode="­" horiz-adv-x="659" d="M84 473zm0 0v152h491V473H84z"/><glyph unicode="®" horiz-adv-x="1704" d="M723 762h108q80 0 128.5 41.5T1008 909q0 75-43 107.5T829 1049H723V762zm434 151q0-80-42.5-141.5T995 680l238-395h-168L858 639H723V285H575v891h261q166 0 243.5-65t77.5-198zM100 731q0 200 100 375t275 276 377 101q200 0 375-100t276-275 101-377q0-197-97-370T1235 84 852-20Q645-20 470 83.5T197.5 360 100 731zm105 0q0-173 87-323.5t237.5-237T852 84q174 0 323 87t236.5 235.5T1499 731q0 174-87 323t-235.5 236.5T852 1378q-174 0-323-87t-236.5-235.5T205 731z"/><glyph unicode="¯" horiz-adv-x="1024" d="M1030 1556H-6v127h1036v-127z"/><glyph unicode="°" horiz-adv-x="877" d="M127 1171q0 130 90.5 221t220.5 91 221-90.5 91-221.5q0-84-41-155.5T595 902t-157-42q-130 0-220.5 90T127 1171zm115 0q0-82 58.5-139T440 975q80 0 137.5 56.5T635 1171q0 84-56.5 140.5T440 1368q-83 0-140.5-57T242 1171z"/><glyph unicode="±" d="M104 1zm549 790h412V653H653V227H514v426H104v138h410v428h139V791zM104 1v138h961V1H104z"/><glyph unicode="²" horiz-adv-x="711" d="M653 586H49v104l236 230q89 86 130 134.5t57.5 86.5 16.5 92q0 68-40 102.5T346 1370q-52 0-101-19t-118-69l-66 88q131 111 283 111 132 0 205.5-65t73.5-177q0-80-44.5-155.5T387 870L213 705h440V586z"/><glyph unicode="³" horiz-adv-x="711" d="M627 1255q0-80-41-131.5T477 1049q176-47 176-209 0-128-92-199.5T301 569q-152 0-268 56v123q147-68 270-68 211 0 211 162 0 145-231 145H166v107h119q103 0 152.5 39.5T487 1241q0 61-40 95t-107 34q-66 0-122-21.5T106 1292l-69 90q63 45 133 72t164 27q136 0 214.5-59.5T627 1255z"/><glyph unicode="´" horiz-adv-x="1182" d="M393 1266q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H393v25z"/><glyph unicode="µ" horiz-adv-x="1268" d="M342 381q0-262 254-262 171 0 250.5 94.5T926 520v576h166V0H956l-26 147h-10Q809-20 580-20q-150 0-238 92h-10q10-84 10-244v-320H176v1588h166V381z"/><glyph unicode="¶" horiz-adv-x="1341" d="M1120-260h-114v1712H793V-260H678v819q-62-18-146-18-216 0-317.5 125T113 1042q0 260 109 387t341 127h557V-260z"/><glyph unicode="·" horiz-adv-x="545" d="M152 723q0 66 31 100.5t87 34.5q58 0 90.5-34.5T393 723q0-65-33-100t-90-35q-51 0-84.5 31.5T152 723z"/><glyph unicode="¸" horiz-adv-x="465" d="M436-289q0-97-76.5-150T133-492q-51 0-96 9v106q45-8 104-8 79 0 119.5 20t40.5 74q0 43-39.5 69.5T113-178L201 0h110l-55-115q180-39 180-174z"/><glyph unicode="¹" horiz-adv-x="711" d="M338 1462h143V586H348v579q0 91 6 181-22-22-49-44.5T143 1184l-67 96z"/><glyph unicode="º" horiz-adv-x="768" d="M702 1135q0-164-85.5-255.5T381 788q-146 0-230.5 93T66 1135q0 163 84 253.5t235 90.5q152 0 234.5-91t82.5-253zm-514 0q0-122 45.5-183T383 891q105 0 151 61t46 183q0 123-46 182t-151 59q-103 0-149-59t-46-182z"/><glyph unicode="»" horiz-adv-x="1018" d="M936 524L592 117l-117 71 287 351-287 350 117 69 344-407v-27zm-395 0L197 117 80 188l287 351L80 889l117 69 344-407v-27z"/><glyph unicode="¼" horiz-adv-x="1597" d="M75 0zm1223 1462L395 0H252l903 1462h143zm-961 0h143V586H347v579q0 91 6 181-22-22-49-44.5T142 1184l-67 96zM1489 203h-125V1h-145v202H817v101l408 579h139V320h125V203zm-270 117v195q0 134 6 209-5-12-17-31.5t-27-42l-30-45-26-39.5-168-246h262z"/><glyph unicode="½" horiz-adv-x="1597" d="M46 0zm1184 1462L327 0H184l903 1462h143zm-922 0h143V586H318v579q0 91 6 181-22-22-49-44.5T113 1184l-67 96zM1499 1H895v104l236 230q89 86 130 134.5t57.5 86.5 16.5 92q0 68-40 102.5T1192 785q-52 0-101-19t-118-69l-66 88q131 111 283 111 132 0 205.5-65t73.5-177q0-80-44.5-155.5T1233 285l-174-165h440V1z"/><glyph unicode="¾" horiz-adv-x="1597" d="M26 0zm594 1255q0-80-41-131.5T470 1049q176-47 176-209 0-128-92-199.5T294 569q-152 0-268 56v123q147-68 270-68 211 0 211 162 0 145-231 145H159v107h119q103 0 152.5 39.5T480 1241q0 61-40 95t-107 34q-66 0-122-21.5T99 1292l-69 90q63 45 133 72t164 27q136 0 214.5-59.5T620 1255zm770 207L487 0H344l903 1462h143zm179-1259h-125V1h-145v202H897v101l408 579h139V320h125V203zm-270 117v195q0 134 6 209-5-12-17-31.5t-27-42l-30-45-26-39.5-168-246h262z"/><glyph unicode="¿" horiz-adv-x="879" d="M590 684v-51q0-122-37.5-196T418 279Q297 173 266.5 135.5t-43-76T211-35q0-100 66-156.5T465-248q80 0 155 19t173 67l59-135q-197-96-395-96-190 0-298 93T51-37q0 70 17.5 122.5t49.5 97 76.5 85.5 98.5 88q101 88 133.5 146T459 653v31h131zm49 299q0-135-121-135-59 0-90 34.5T397 983q0 64 33 99.5t88 35.5q51 0 86-32t35-103z"/><glyph unicode="À" horiz-adv-x="1296" d="M0 0zm1120 0L938 465H352L172 0H0l578 1468h143L1296 0h-176zM885 618l-170 453q-33 86-68 211-22-96-63-211L412 618h473zm-161 961H614q-65 52-154 148t-129 159v21h203q32-69 89-159.5T724 1604v-25z"/><glyph unicode="Á" horiz-adv-x="1296" d="M0 0zm1120 0L938 465H352L172 0H0l578 1468h143L1296 0h-176zM885 618l-170 453q-33 86-68 211-22-96-63-211L412 618h473zm-359 986q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H526v25z"/><glyph unicode="Â" horiz-adv-x="1296" d="M0 0zm1120 0L938 465H352L172 0H0l578 1468h143L1296 0h-176zM885 618l-170 453q-33 86-68 211-22-96-63-211L412 618h473zm-582 984q127 136 178 200t74 105h166q22-42 76.5-108.5T977 1602v-23H858q-88 55-221 186-136-134-219-186H303v23z"/><glyph unicode="Ã" horiz-adv-x="1296" d="M0 0zm1120 0L938 465H352L172 0H0l578 1468h143L1296 0h-176zM885 618l-170 453q-33 86-68 211-22-96-63-211L412 618h473zm-93 963q-43 0-84 18.5t-80.5 41-76 41T481 1700q-50 0-75.5-30t-39.5-91h-98q13 121 70.5 189.5T487 1837q46 0 89-18.5t82-41 75-41 68-18.5q49 0 73 29.5t39 91.5h99q-13-121-69.5-189.5T792 1581z"/><glyph unicode="Ä" horiz-adv-x="1296" d="M0 0zm1120 0L938 465H352L172 0H0l578 1468h143L1296 0h-176zM885 618l-170 453q-33 86-68 211-22-96-63-211L412 618h473zM364 1731q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T454 1632q-37 0-63.5 24.5T364 1731zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T835 1632t-63.5 24.5T745 1731z"/><glyph unicode="Å" horiz-adv-x="1296" d="M0 0zm1120 0L938 465H352L172 0H0l578 1468h143L1296 0h-176zM885 618l-170 453q-33 86-68 211-22-96-63-211L412 618h473zm-15 969q0-98-61.5-157.5T645 1370q-101 0-161 58.5T424 1585t60.5 155.5T645 1798q101 0 163-59.5t62-151.5zm-108-2q0 56-33 86.5t-84 30.5-84-30.5-33-86.5 30-86.5 87-30.5q52 0 84.5 30.5T762 1585z"/><glyph unicode="Æ" horiz-adv-x="1788" d="M1665 0H915v465H401L174 0H-2l698 1462h969v-151h-580V840h541V690h-541V152h580V0zM469 618h446v693H797z"/><glyph unicode="Ç" horiz-adv-x="1292" d="M125 0zm702 1331q-241 0-380.5-160.5T307 731q0-287 134.5-443.5T825 131q153 0 349 55V37q-152-57-375-57-323 0-498.5 196T125 733q0 226 84.5 396t244 262 375.5 92q230 0 402-84l-72-146q-166 78-332 78zM950-289q0-97-76.5-150T647-492q-51 0-96 9v106q45-8 104-8 79 0 119.5 20t40.5 74q0 43-39.5 69.5T627-178L715 0h110l-55-115q180-39 180-174z"/><glyph unicode="È" horiz-adv-x="1139" d="M201 0zm815 0H201v1462h815v-151H371V840h606V690H371V152h645V0zM713 1579H603q-65 52-154 148t-129 159v21h203q32-69 89-159.5T713 1604v-25z"/><glyph unicode="É" horiz-adv-x="1139" d="M201 0zm815 0H201v1462h815v-151H371V840h606V690H371V152h645V0zM456 1604q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H456v25z"/><glyph unicode="Ê" horiz-adv-x="1139" d="M201 0zm815 0H201v1462h815v-151H371V840h606V690H371V152h645V0zM263 1602q127 136 178 200t74 105h166q22-42 76.5-108.5T937 1602v-23H818q-88 55-221 186-136-134-219-186H263v23z"/><glyph unicode="Ë" horiz-adv-x="1139" d="M201 0zm815 0H201v1462h815v-151H371V840h606V690H371V152h645V0zM327 1731q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T417 1632q-37 0-63.5 24.5T327 1731zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T798 1632t-63.5 24.5T708 1731z"/><glyph unicode="Ì" horiz-adv-x="571" d="M5 0zm196 0v1462h170V0H201zm197 1579H288q-65 52-154 148T5 1886v21h203q32-69 89-159.5T398 1604v-25z"/><glyph unicode="Í" horiz-adv-x="571" d="M179 0zm22 0v1462h170V0H201zm-22 1604q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H179v25z"/><glyph unicode="Î" horiz-adv-x="571" d="M0 0zm201 0v1462h170V0H201zM-57 1602q127 136 178 200t74 105h166q22-42 76.5-108.5T617 1602v-23H498q-88 55-221 186-136-134-219-186H-57v23z"/><glyph unicode="Ï" horiz-adv-x="571" d="M5 0zm196 0v1462h170V0H201zM5 1731q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T95 1632q-37 0-63.5 24.5T5 1731zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T476 1632t-63.5 24.5T386 1731z"/><glyph unicode="Ð" horiz-adv-x="1479" d="M1352 745q0-362-196.5-553.5T590 0H201v649H47v150h154v663h434q337 0 527-187.5T1352 745zm-181-6q0 576-569 576H371V799h379V649H371V147h190q610 0 610 592z"/><glyph unicode="Ñ" horiz-adv-x="1544" d="M201 0zm1142 0h-194L350 1227h-8q16-216 16-396V0H201v1462h192l797-1222h8q-2 27-9 173.5t-5 209.5v839h159V0zM935 1581q-43 0-84 18.5t-80.5 41-76 41T624 1700q-50 0-75.5-30t-39.5-91h-98q13 121 70.5 189.5T630 1837q46 0 89-18.5t82-41 75-41 68-18.5q49 0 73 29.5t39 91.5h99q-13-121-69.5-189.5T935 1581z"/><glyph unicode="Ò" horiz-adv-x="1595" d="M125 0zm1345 733q0-351-177.5-552T799-20q-323 0-498.5 197.5T125 735q0 357 176 553.5T801 1485q315 0 492-200t177-552zm-1165 0q0-297 126.5-450.5T799 129q243 0 367 153t124 451q0 295-123.5 447.5T801 1333q-243 0-369.5-153.5T305 733zm602 846H797q-65 52-154 148t-129 159v21h203q32-69 89-159.5T907 1604v-25z"/><glyph unicode="Ó" horiz-adv-x="1595" d="M125 0zm1345 733q0-351-177.5-552T799-20q-323 0-498.5 197.5T125 735q0 357 176 553.5T801 1485q315 0 492-200t177-552zm-1165 0q0-297 126.5-450.5T799 129q243 0 367 153t124 451q0 295-123.5 447.5T801 1333q-243 0-369.5-153.5T305 733zm354 871q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H659v25z"/><glyph unicode="Ô" horiz-adv-x="1595" d="M125 0zm1345 733q0-351-177.5-552T799-20q-323 0-498.5 197.5T125 735q0 357 176 553.5T801 1485q315 0 492-200t177-552zm-1165 0q0-297 126.5-450.5T799 129q243 0 367 153t124 451q0 295-123.5 447.5T801 1333q-243 0-369.5-153.5T305 733zm143 869q127 136 178 200t74 105h166q22-42 76.5-108.5T1122 1602v-23h-119q-88 55-221 186-136-134-219-186H448v23z"/><glyph unicode="Õ" horiz-adv-x="1595" d="M125 0zm1345 733q0-351-177.5-552T799-20q-323 0-498.5 197.5T125 735q0 357 176 553.5T801 1485q315 0 492-200t177-552zm-1165 0q0-297 126.5-450.5T799 129q243 0 367 153t124 451q0 295-123.5 447.5T801 1333q-243 0-369.5-153.5T305 733zm637 848q-43 0-84 18.5t-80.5 41-76 41T631 1700q-50 0-75.5-30t-39.5-91h-98q13 121 70.5 189.5T637 1837q46 0 89-18.5t82-41 75-41 68-18.5q49 0 73 29.5t39 91.5h99q-13-121-69.5-189.5T942 1581z"/><glyph unicode="Ö" horiz-adv-x="1595" d="M125 0zm1345 733q0-351-177.5-552T799-20q-323 0-498.5 197.5T125 735q0 357 176 553.5T801 1485q315 0 492-200t177-552zm-1165 0q0-297 126.5-450.5T799 129q243 0 367 153t124 451q0 295-123.5 447.5T801 1333q-243 0-369.5-153.5T305 733zm217 998q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T612 1632q-37 0-63.5 24.5T522 1731zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T993 1632t-63.5 24.5T903 1731z"/><glyph unicode="×" d="M940 1176l96-99-352-354 350-352-96-99-354 351-348-351-101 99 350 352-352 352 100 101 353-355z"/><glyph unicode="Ø" horiz-adv-x="1595" d="M1470 733q0-351-177.5-552T799-20Q564-20 416 80L315-61 195 18l108 154Q125 370 125 735q0 357 176 553.5T801 1485q209 0 366-94l97 135 120-80-106-148q192-202 192-565zm-180 0q0 272-110 426L508 211q115-82 291-82 243 0 367 153t124 451zm-985 0q0-262 101-416l669 943q-106 73-274 73-243 0-369.5-153.5T305 733z"/><glyph unicode="Ù" horiz-adv-x="1491" d="M186 0zm1119 1462V516q0-250-151-393T739-20 330.5 124 186 520v942h170V508q0-183 100-281t294-98q185 0 285 98.5T1135 510v952h170zm-449 117H746q-65 52-154 148t-129 159v21h203q32-69 89-159.5T856 1604v-25z"/><glyph unicode="Ú" horiz-adv-x="1491" d="M186 0zm1119 1462V516q0-250-151-393T739-20 330.5 124 186 520v942h170V508q0-183 100-281t294-98q185 0 285 98.5T1135 510v952h170zm-705 142q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H600v25z"/><glyph unicode="Û" horiz-adv-x="1491" d="M186 0zm1119 1462V516q0-250-151-393T739-20 330.5 124 186 520v942h170V508q0-183 100-281t294-98q185 0 285 98.5T1135 510v952h170zm-912 140q127 136 178 200t74 105h166q22-42 76.5-108.5T1067 1602v-23H948q-88 55-221 186-136-134-219-186H393v23z"/><glyph unicode="Ü" horiz-adv-x="1491" d="M186 0zm1119 1462V516q0-250-151-393T739-20 330.5 124 186 520v942h170V508q0-183 100-281t294-98q185 0 285 98.5T1135 510v952h170zm-844 269q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T551 1632q-37 0-63.5 24.5T461 1731zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T932 1632t-63.5 24.5T842 1731z"/><glyph unicode="Ý" horiz-adv-x="1147" d="M0 0zm573 731l390 731h184L659 567V0H487v559L0 1462h186zm-131 873q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H442v25z"/><glyph unicode="Þ" horiz-adv-x="1251" d="M1145 784q0-227-151.5-346T555 319H371V0H201v1462h170v-256h215q281 0 420-103.5T1145 784zM371 465h168q226 0 327 71.5T967 772q0 149-95 218t-297 69H371V465z"/><glyph unicode="ß" horiz-adv-x="1274" d="M1049 1266q0-135-143-250-88-70-116-103.5T762 846q0-32 13.5-53t49-49.5T938 664q140-95 191-173.5t51-179.5q0-160-97-245.5T807-20q-188 0-295 69v154q63-39 141-62.5T803 117q215 0 215 182 0 75-41.5 128.5T825 551q-127 82-175 143.5T602 840q0 63 34.5 116T742 1062q75 57 107 102t32 98q0 80-68 122.5T618 1427q-276 0-276-223V0H176v1202q0 178 110 271.5t332 93.5q206 0 318.5-78.5T1049 1266z"/><glyph unicode="à" horiz-adv-x="1139" d="M94 0zm756 0l-33 156h-8Q727 53 645.5 16.5T442-20q-163 0-255.5 84T94 303q0 332 531 348l186 6v68q0 129-55.5 190.5T578 977q-137 0-310-84l-51 127q81 44 177.5 69t193.5 25q196 0 290.5-87T973 748V0H850zM475 117q155 0 243.5 85T807 440v99l-166-7q-198-7-285.5-61.5T268 301q0-90 54.5-137T475 117zm197 1124H562q-65 52-154 148t-129 159v21h203q32-69 89-159.5T672 1266v-25z"/><glyph unicode="á" horiz-adv-x="1139" d="M94 0zm756 0l-33 156h-8Q727 53 645.5 16.5T442-20q-163 0-255.5 84T94 303q0 332 531 348l186 6v68q0 129-55.5 190.5T578 977q-137 0-310-84l-51 127q81 44 177.5 69t193.5 25q196 0 290.5-87T973 748V0H850zM475 117q155 0 243.5 85T807 440v99l-166-7q-198-7-285.5-61.5T268 301q0-90 54.5-137T475 117zm-39 1149q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H436v25z"/><glyph unicode="â" horiz-adv-x="1139" d="M94 0zm756 0l-33 156h-8Q727 53 645.5 16.5T442-20q-163 0-255.5 84T94 303q0 332 531 348l186 6v68q0 129-55.5 190.5T578 977q-137 0-310-84l-51 127q81 44 177.5 69t193.5 25q196 0 290.5-87T973 748V0H850zM475 117q155 0 243.5 85T807 440v99l-166-7q-198-7-285.5-61.5T268 301q0-90 54.5-137T475 117zM228 1264q127 136 178 200t74 105h166q22-42 76.5-108.5T902 1264v-23H783q-88 55-221 186-136-134-219-186H228v23z"/><glyph unicode="ã" horiz-adv-x="1139" d="M94 0zm756 0l-33 156h-8Q727 53 645.5 16.5T442-20q-163 0-255.5 84T94 303q0 332 531 348l186 6v68q0 129-55.5 190.5T578 977q-137 0-310-84l-51 127q81 44 177.5 69t193.5 25q196 0 290.5-87T973 748V0H850zM475 117q155 0 243.5 85T807 440v99l-166-7q-198-7-285.5-61.5T268 301q0-90 54.5-137T475 117zm246 1126q-43 0-84 18.5t-80.5 41-76 41T410 1362q-50 0-75.5-30t-39.5-91h-98q13 121 70.5 189.5T416 1499q46 0 89-18.5t82-41 75-41 68-18.5q49 0 73 29.5t39 91.5h99q-13-121-69.5-189.5T721 1243z"/><glyph unicode="ä" horiz-adv-x="1139" d="M94 0zm756 0l-33 156h-8Q727 53 645.5 16.5T442-20q-163 0-255.5 84T94 303q0 332 531 348l186 6v68q0 129-55.5 190.5T578 977q-137 0-310-84l-51 127q81 44 177.5 69t193.5 25q196 0 290.5-87T973 748V0H850zM475 117q155 0 243.5 85T807 440v99l-166-7q-198-7-285.5-61.5T268 301q0-90 54.5-137T475 117zM279 1393q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T369 1294q-37 0-63.5 24.5T279 1393zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T750 1294t-63.5 24.5T660 1393z"/><glyph unicode="å" horiz-adv-x="1139" d="M94 0zm756 0l-33 156h-8Q727 53 645.5 16.5T442-20q-163 0-255.5 84T94 303q0 332 531 348l186 6v68q0 129-55.5 190.5T578 977q-137 0-310-84l-51 127q81 44 177.5 69t193.5 25q196 0 290.5-87T973 748V0H850zM475 117q155 0 243.5 85T807 440v99l-166-7q-198-7-285.5-61.5T268 301q0-90 54.5-137T475 117zm329 1341q0-98-61.5-157.5T579 1241q-101 0-161 58.5T358 1456t60.5 155.5T579 1669q101 0 163-59.5t62-151.5zm-108-2q0 56-33 86.5t-84 30.5-84-30.5-33-86.5 30-86.5 87-30.5q52 0 84.5 30.5T696 1456z"/><glyph unicode="æ" horiz-adv-x="1757" d="M94 303q0 161 124 250.5T596 651l184 6v68q0 129-58 190.5T545 977q-144 0-307-84l-52 127q74 41 173.5 67.5T557 1114q130 0 212.5-43.5T893 932q53 88 138.5 136t195.5 48q192 0 308-133.5T1651 627V520H950q8-395 322-395 91 0 169.5 17.5T1604 199V51q-86-38-160.5-54.5T1268-20q-289 0-414 233Q773 86 674.5 33T442-20q-163 0-255.5 85T94 303zm174-2q0-95 53.5-139.5T463 117q145 0 229 84.5T776 440v99l-158-7q-186-8-268-62.5T268 301zm957 676q-121 0-190.5-83T954 653h519q0 156-64 240t-184 84z"/><glyph unicode="ç" horiz-adv-x="975" d="M115 0zm499-20q-238 0-368.5 146.5T115 541q0 275 132.5 425T625 1116q79 0 158-17t124-40l-51-141q-55 22-120 36.5T621 969q-334 0-334-426 0-202 81.5-310T610 125q137 0 281 59V37Q781-20 614-20zm148-269q0-97-76.5-150T459-492q-51 0-96 9v106q45-8 104-8 79 0 119.5 20t40.5 74q0 43-39.5 69.5T439-178L527 0h110l-55-115q180-39 180-174z"/><glyph unicode="è" horiz-adv-x="1149" d="M115 0zm524-20q-243 0-383.5 148T115 539q0 265 130.5 421T596 1116q206 0 326-135.5T1042 623V518H287q5-193 97.5-293T645 125q177 0 350 74V51Q907 13 828.5-3.5T639-20zm-45 997q-132 0-210.5-86T291 653h573q0 157-70 240.5T594 977zm117 264H601q-65 52-154 148t-129 159v21h203q32-69 89-159.5T711 1266v-25z"/><glyph unicode="é" horiz-adv-x="1149" d="M115 0zm524-20q-243 0-383.5 148T115 539q0 265 130.5 421T596 1116q206 0 326-135.5T1042 623V518H287q5-193 97.5-293T645 125q177 0 350 74V51Q907 13 828.5-3.5T639-20zm-45 997q-132 0-210.5-86T291 653h573q0 157-70 240.5T594 977zm-123 289q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H471v25z"/><glyph unicode="ê" horiz-adv-x="1149" d="M115 0zm524-20q-243 0-383.5 148T115 539q0 265 130.5 421T596 1116q206 0 326-135.5T1042 623V518H287q5-193 97.5-293T645 125q177 0 350 74V51Q907 13 828.5-3.5T639-20zm-45 997q-132 0-210.5-86T291 653h573q0 157-70 240.5T594 977zm-335 287q127 136 178 200t74 105h166q22-42 76.5-108.5T933 1264v-23H814q-88 55-221 186-136-134-219-186H259v23z"/><glyph unicode="ë" horiz-adv-x="1149" d="M115 0zm524-20q-243 0-383.5 148T115 539q0 265 130.5 421T596 1116q206 0 326-135.5T1042 623V518H287q5-193 97.5-293T645 125q177 0 350 74V51Q907 13 828.5-3.5T639-20zm-45 997q-132 0-210.5-86T291 653h573q0 157-70 240.5T594 977zm-275 416q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T409 1294q-37 0-63.5 24.5T319 1393zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T790 1294t-63.5 24.5T700 1393z"/><glyph unicode="ì" horiz-adv-x="518" d="M0 0zm342 0H176v1096h166V0zm13 1241H245q-65 52-154 148t-129 159v21h203q32-69 89-159.5T355 1266v-25z"/><glyph unicode="í" horiz-adv-x="518" d="M169 0zm173 0H176v1096h166V0zM169 1266q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H169v25z"/><glyph unicode="î" horiz-adv-x="518" d="M0 0zm342 0H176v1096h166V0zM-77 1264q127 136 178 200t74 105h166q22-42 76.5-108.5T597 1264v-23H478q-88 55-221 186-136-134-219-186H-77v23z"/><glyph unicode="ï" horiz-adv-x="518" d="M0 0zm342 0H176v1096h166V0zM-20 1393q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T70 1294q-37 0-63.5 24.5T-20 1393zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T451 1294t-63.5 24.5T361 1393z"/><glyph unicode="ð" horiz-adv-x="1221" d="M1122 563q0-281-130.5-432T614-20q-222 0-361.5 134.5T113 475q0 230 131.5 361T596 967q226 0 326-121l8 4q-57 214-262 405l-271-155-73 108 233 133q-92 62-186 111l69 117q156-73 258-148l238 138 76-107-207-119q152-143 234.5-342t82.5-428zm-168-51q0 147-90 232t-246 85q-337 0-337-360 0-167 87.5-258.5T618 119q175 0 255.5 100.5T954 512z"/><glyph unicode="ñ" horiz-adv-x="1257" d="M176 0zm750 0v709q0 134-61 200t-191 66q-172 0-252-93t-80-307V0H176v1096h135l27-150h8q51 81 143 125.5t205 44.5q198 0 298-95.5T1092 715V0H926zM802 1243q-43 0-84 18.5t-80.5 41-76 41T491 1362q-50 0-75.5-30t-39.5-91h-98q13 121 70.5 189.5T497 1499q46 0 89-18.5t82-41 75-41 68-18.5q49 0 73 29.5t39 91.5h99q-13-121-69.5-189.5T802 1243z"/><glyph unicode="ò" horiz-adv-x="1237" d="M115 0zm1007 549q0-268-135-418.5T614-20q-147 0-261 69T177 247t-62 302q0 268 134 417.5T621 1116q230 0 365.5-153T1122 549zm-835 0q0-210 84-320t247-110 247.5 109.5T950 549q0 209-84.5 317.5T616 975q-163 0-246-107t-83-319zm455 692H632q-65 52-154 148t-129 159v21h203q32-69 89-159.5T742 1266v-25z"/><glyph unicode="ó" horiz-adv-x="1237" d="M115 0zm1007 549q0-268-135-418.5T614-20q-147 0-261 69T177 247t-62 302q0 268 134 417.5T621 1116q230 0 365.5-153T1122 549zm-835 0q0-210 84-320t247-110 247.5 109.5T950 549q0 209-84.5 317.5T616 975q-163 0-246-107t-83-319zm192 717q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H479v25z"/><glyph unicode="ô" horiz-adv-x="1237" d="M115 0zm1007 549q0-268-135-418.5T614-20q-147 0-261 69T177 247t-62 302q0 268 134 417.5T621 1116q230 0 365.5-153T1122 549zm-835 0q0-210 84-320t247-110 247.5 109.5T950 549q0 209-84.5 317.5T616 975q-163 0-246-107t-83-319zm-5 715q127 136 178 200t74 105h166q22-42 76.5-108.5T956 1264v-23H837q-88 55-221 186-136-134-219-186H282v23z"/><glyph unicode="õ" horiz-adv-x="1237" d="M115 0zm1007 549q0-268-135-418.5T614-20q-147 0-261 69T177 247t-62 302q0 268 134 417.5T621 1116q230 0 365.5-153T1122 549zm-835 0q0-210 84-320t247-110 247.5 109.5T950 549q0 209-84.5 317.5T616 975q-163 0-246-107t-83-319zm486 694q-43 0-84 18.5t-80.5 41-76 41T462 1362q-50 0-75.5-30t-39.5-91h-98q13 121 70.5 189.5T468 1499q46 0 89-18.5t82-41 75-41 68-18.5q49 0 73 29.5t39 91.5h99q-13-121-69.5-189.5T773 1243z"/><glyph unicode="ö" horiz-adv-x="1237" d="M115 0zm1007 549q0-268-135-418.5T614-20q-147 0-261 69T177 247t-62 302q0 268 134 417.5T621 1116q230 0 365.5-153T1122 549zm-835 0q0-210 84-320t247-110 247.5 109.5T950 549q0 209-84.5 317.5T616 975q-163 0-246-107t-83-319zm49 844q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T426 1294q-37 0-63.5 24.5T336 1393zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T807 1294t-63.5 24.5T717 1393z"/><glyph unicode="÷" d="M104 653v138h961V653H104zm367-280q0 60 29.5 90.5T584 494q52 0 81-31.5t29-89.5q0-57-29.5-89T584 252q-52 0-82.5 31.5T471 373zm0 698q0 60 29.5 90.5T584 1192q52 0 81-31.5t29-89.5q0-57-29.5-89T584 950q-52 0-82.5 31.5T471 1071z"/><glyph unicode="ø" horiz-adv-x="1237" d="M1122 549q0-268-135-418.5T614-20q-154 0-266 69L264-68 150 10l94 131Q115 293 115 549q0 268 134 417.5T621 1116q154 0 270-76l84 119 117-76-97-133q127-152 127-401zm-835 0q0-171 53-273l465 646q-75 53-189 53-163 0-246-107t-83-319zm663 0q0 164-51 264L434 170q71-51 184-51 163 0 247.5 109.5T950 549z"/><glyph unicode="ù" horiz-adv-x="1257" d="M164 0zm168 1096V385q0-134 61-200t191-66q172 0 251.5 94T915 520v576h166V0H944l-24 147h-9Q860 66 769.5 23T563-20q-200 0-299.5 95T164 379v717h168zm394 145H616q-65 52-154 148t-129 159v21h203q32-69 89-159.5T726 1266v-25z"/><glyph unicode="ú" horiz-adv-x="1257" d="M164 0zm168 1096V385q0-134 61-200t191-66q172 0 251.5 94T915 520v576h166V0H944l-24 147h-9Q860 66 769.5 23T563-20q-200 0-299.5 95T164 379v717h168zm174 170q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H506v25z"/><glyph unicode="û" horiz-adv-x="1257" d="M164 0zm168 1096V385q0-134 61-200t191-66q172 0 251.5 94T915 520v576h166V0H944l-24 147h-9Q860 66 769.5 23T563-20q-200 0-299.5 95T164 379v717h168zm-46 168q127 136 178 200t74 105h166q22-42 76.5-108.5T960 1264v-23H841q-88 55-221 186-136-134-219-186H286v23z"/><glyph unicode="ü" horiz-adv-x="1257" d="M164 0zm168 1096V385q0-134 61-200t191-66q172 0 251.5 94T915 520v576h166V0H944l-24 147h-9Q860 66 769.5 23T563-20q-200 0-299.5 95T164 379v717h168zm10 297q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T432 1294q-37 0-63.5 24.5T342 1393zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T813 1294t-63.5 24.5T723 1393z"/><glyph unicode="ý" horiz-adv-x="1032" d="M2 0zm0 1096h178l240-625q79-214 98-309h8q13 51 54.5 174.5T852 1096h178L559-152q-70-185-163.5-262.5T166-492q-76 0-150 17v133q55-12 123-12 171 0 244 192L444-6zm409 170q48 62 103.5 150t87.5 153h202v-21q-44-65-131-160t-151-147H411v25z"/><glyph unicode="þ" horiz-adv-x="1255" d="M344 948q66 89 151 128.5t191 39.5q215 0 335-150t120-417q0-268-120.5-418.5T686-20q-222 0-344 161h-12l4-34q8-77 8-140v-459H176v2048h166v-466q0-52-6-142h8zm320 27q-168 0-244-92t-78-293v-41q0-231 77-330.5T666 119q303 0 303 432 0 215-74 319.5T664 975z"/><glyph unicode="ÿ" horiz-adv-x="1032" d="M2 0zm0 1096h178l240-625q79-214 98-309h8q13 51 54.5 174.5T852 1096h178L559-152q-70-185-163.5-262.5T166-492q-76 0-150 17v133q55-12 123-12 171 0 244 192L444-6zm232 297q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T324 1294q-37 0-63.5 24.5T234 1393zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T705 1294t-63.5 24.5T615 1393z"/><glyph unicode="ı" horiz-adv-x="518" d="M342 0H176v1096h166V0z"/><glyph unicode="Œ" horiz-adv-x="1890" d="M1767 0H999Q897-20 805-20q-327 0-503.5 196.5T125 735q0 360 174 555t494 195q102 0 192-23h782v-151h-589V840h551V690h-551V152h589V0zM811 1333q-249 0-377.5-152.5T305 733q0-297 128.5-450.5T809 129q112 0 199 33v1141q-87 30-197 30z"/><glyph unicode="œ" horiz-adv-x="1929" d="M1430-20q-293 0-418 235Q950 99 845.5 39.5T604-20q-223 0-357 152.5T113 549q0 265 131 415t366 150q131 0 233.5-59.5T1008 881q58 112 154 172.5t222 60.5q201 0 320-132.5T1823 623V518h-729q8-393 338-393 94 0 174.5 17.5T1774 199V51q-88-39-164-55t-180-16zM287 549q0-211 76-320.5T606 119q163 0 239.5 106.5T922 541q0 221-77.5 327.5T602 975q-166 0-240.5-108T287 549zm1095 426q-127 0-199.5-82T1098 653h544q0 158-66 240t-194 82z"/><glyph unicode="Ÿ" horiz-adv-x="1147" d="M0 0zm573 731l390 731h184L659 567V0H487v559L0 1462h186zM294 1731q0 52 26.5 75t63.5 23q38 0 65.5-23t27.5-75q0-50-27.5-74.5T384 1632q-37 0-63.5 24.5T294 1731zm381 0q0 52 26.5 75t63.5 23 64.5-23 27.5-75q0-50-27.5-74.5T765 1632t-63.5 24.5T675 1731z"/><glyph unicode="ˆ" horiz-adv-x="1212" d="M268 1264q127 136 178 200t74 105h166q22-42 76.5-108.5T942 1264v-23H823q-88 55-221 186-136-134-219-186H268v23z"/><glyph unicode="˚" horiz-adv-x="1182" d="M813 1458q0-98-61.5-157.5T588 1241q-101 0-161 58.5T367 1456t60.5 155.5T588 1669q101 0 163-59.5t62-151.5zm-108-2q0 56-33 86.5t-84 30.5-84-30.5-33-86.5 30-86.5 87-30.5q52 0 84.5 30.5T705 1456z"/><glyph unicode="˜" horiz-adv-x="1212" d="M788 1243q-43 0-84 18.5t-80.5 41-76 41T477 1362q-50 0-75.5-30t-39.5-91h-98q13 121 70.5 189.5T483 1499q46 0 89-18.5t82-41 75-41 68-18.5q49 0 73 29.5t39 91.5h99q-13-121-69.5-189.5T788 1243z"/><glyph horiz-adv-x="953"/><glyph horiz-adv-x="1907"/><glyph horiz-adv-x="953"/><glyph horiz-adv-x="1907"/><glyph horiz-adv-x="635"/><glyph horiz-adv-x="476"/><glyph horiz-adv-x="317"/><glyph horiz-adv-x="317"/><glyph horiz-adv-x="238"/><glyph horiz-adv-x="381"/><glyph horiz-adv-x="105"/><glyph unicode="‐" horiz-adv-x="659" d="M84 473v152h491V473H84z"/><glyph unicode="‑" horiz-adv-x="659" d="M84 473v152h491V473H84z"/><glyph unicode="‒" horiz-adv-x="659" d="M84 473v152h491V473H84z"/><glyph unicode="–" horiz-adv-x="1024" d="M82 473v152h860V473H82z"/><glyph unicode="—" horiz-adv-x="2048" d="M82 473v152h1884V473H82z"/><glyph unicode="‘" horiz-adv-x="348" d="M37 961l-12 22q22 90 71 224t105 255h123q-66-254-103-501H37z"/><glyph unicode="’" horiz-adv-x="348" d="M309 1462l15-22q-26-100-75-232.5T147 961H25q70 285 102 501h182z"/><glyph unicode="‚" horiz-adv-x="502" d="M63 0zm287 238l15-23q-26-100-75-232.5T188-264H63Q90-160 122.5-7T168 238h182z"/><glyph unicode="“" horiz-adv-x="717" d="M406 961l-15 22q56 215 178 479h123q-30-115-59.5-259.5T590 961H406zm-369 0l-12 22q22 90 71 224t105 255h123q-66-254-103-501H37z"/><glyph unicode="”" horiz-adv-x="717" d="M309 1462l15-22q-26-100-75-232.5T147 961H25q70 285 102 501h182zm369 0l14-22q-24-91-72-224T516 961H391q26 100 59 254t46 247h182z"/><glyph unicode="„" horiz-adv-x="829" d="M25 0zm284 238l15-22q-26-100-75-232.5T147-263H25Q95 22 127 238h182zm369 0l14-22q-24-91-72-224T516-263H391q26 100 59 254t46 247h182z"/><glyph unicode="•" horiz-adv-x="770" d="M164 748q0 121 56.5 184T385 995q105 0 163-62t58-185q0-119-57.5-183.5T385 500q-107 0-164 65.5T164 748z"/><glyph unicode="…" horiz-adv-x="1606" d="M152 0zm0 106q0 67 30.5 101.5T270 242q58 0 90.5-34.5T393 106q0-65-33-100t-90-35q-51 0-84.5 31.5T152 106zm530 0q0 67 30.5 101.5T800 242q58 0 90.5-34.5T923 106q0-65-33-100t-90-35q-51 0-84.5 31.5T682 106zm531 0q0 67 30.5 101.5T1331 242q58 0 90.5-34.5T1454 106q0-65-33-100t-90-35q-51 0-84.5 31.5T1213 106z"/><glyph horiz-adv-x="381"/><glyph unicode="‹" horiz-adv-x="623" d="M82 551l342 407 119-69-289-350 289-351-119-71L82 524v27z"/><glyph unicode="›" horiz-adv-x="623" d="M541 524L197 117 80 188l287 351L80 889l117 69 344-407v-27z"/><glyph unicode="⁄" horiz-adv-x="266" d="M655 1462L-248 0h-143l903 1462h143z"/><glyph horiz-adv-x="476"/><glyph unicode="⁴" horiz-adv-x="711" d="M692 788H567V586H422v202H20v101l408 579h139V905h125V788zM422 905v195q0 134 6 209-5-12-17-31.5t-27-42l-30-45-26-39.5-168-246h262z"/><glyph unicode="€" horiz-adv-x="1208" d="M795 1333q-319 0-398-403h510V801H383l-2-57v-64l2-45h463V506H399q37-180 138.5-278.5T809 129q156 0 309 66V45Q972-20 801-20q-237 0-381.5 134.5T229 506H63v129h152l-2 42v44l2 80H63v129h164q39 261 185 407t383 146q201 0 366-97l-71-139q-166 86-295 86z"/><glyph unicode="™" horiz-adv-x="1589" d="M369 741H246v615H37v106h543v-106H369V741zm600 0l-201 559h-8l6-129V741H647v721h187l196-559 203 559h180V741h-127v420l6 137h-8l-211-557H969z"/><glyph unicode="−" d="M104 653v138h961V653H104z"/><glyph unicode="" horiz-adv-x="1095" d="M0 1095h1095V0H0v1095z"/><glyph horiz-adv-x="1255" d="M0 0z"/><hkern u1="&quot;" u2="Ÿ" k="-20"/><hkern u1="&quot;" u2="œ" k="123"/><hkern u1="&quot;" u2="ü" k="61"/><hkern u1="&quot;" u2="û" k="61"/><hkern u1="&quot;" u2="ú" k="61"/><hkern u1="&quot;" u2="ù" k="61"/><hkern u1="&quot;" u2="ø" k="123"/><hkern u1="&quot;" u2="ö" k="123"/><hkern u1="&quot;" u2="õ" k="123"/><hkern u1="&quot;" u2="ô" k="123"/><hkern u1="&quot;" u2="ó" k="123"/><hkern u1="&quot;" u2="ò" k="123"/><hkern u1="&quot;" u2="ë" k="123"/><hkern u1="&quot;" u2="ê" k="123"/><hkern u1="&quot;" u2="é" k="123"/><hkern u1="&quot;" u2="è" k="123"/><hkern u1="&quot;" u2="ç" k="123"/><hkern u1="&quot;" u2="æ" k="82"/><hkern u1="&quot;" u2="å" k="82"/><hkern u1="&quot;" u2="ä" k="82"/><hkern u1="&quot;" u2="ã" k="82"/><hkern u1="&quot;" u2="â" k="82"/><hkern u1="&quot;" u2="á" k="82"/><hkern u1="&quot;" u2="à" k="123"/><hkern u1="&quot;" u2="Ý" k="-20"/><hkern u1="&quot;" u2="Å" k="143"/><hkern u1="&quot;" u2="Ä" k="143"/><hkern u1="&quot;" u2="Ã" k="143"/><hkern u1="&quot;" u2="Â" k="143"/><hkern u1="&quot;" u2="Á" k="143"/><hkern u1="&quot;" u2="À" k="143"/><hkern u1="&quot;" u2="u" k="61"/><hkern u1="&quot;" u2="s" k="61"/><hkern u1="&quot;" u2="r" k="61"/><hkern u1="&quot;" u2="q" k="123"/><hkern u1="&quot;" u2="p" k="61"/><hkern u1="&quot;" u2="o" k="123"/><hkern u1="&quot;" u2="n" k="61"/><hkern u1="&quot;" u2="m" k="61"/><hkern u1="&quot;" u2="g" k="61"/><hkern u1="&quot;" u2="e" k="123"/><hkern u1="&quot;" u2="d" k="123"/><hkern u1="&quot;" u2="c" k="123"/><hkern u1="&quot;" u2="a" k="82"/><hkern u1="&quot;" u2="Y" k="-20"/><hkern u1="&quot;" u2="W" k="-41"/><hkern u1="&quot;" u2="V" k="-41"/><hkern u1="&quot;" u2="T" k="-41"/><hkern u1="&quot;" u2="A" k="143"/><hkern u1="'" u2="Ÿ" k="-20"/><hkern u1="'" u2="œ" k="123"/><hkern u1="'" u2="ü" k="61"/><hkern u1="'" u2="û" k="61"/><hkern u1="'" u2="ú" k="61"/><hkern u1="'" u2="ù" k="61"/><hkern u1="'" u2="ø" k="123"/><hkern u1="'" u2="ö" k="123"/><hkern u1="'" u2="õ" k="123"/><hkern u1="'" u2="ô" k="123"/><hkern u1="'" u2="ó" k="123"/><hkern u1="'" u2="ò" k="123"/><hkern u1="'" u2="ë" k="123"/><hkern u1="'" u2="ê" k="123"/><hkern u1="'" u2="é" k="123"/><hkern u1="'" u2="è" k="123"/><hkern u1="'" u2="ç" k="123"/><hkern u1="'" u2="æ" k="82"/><hkern u1="'" u2="å" k="82"/><hkern u1="'" u2="ä" k="82"/><hkern u1="'" u2="ã" k="82"/><hkern u1="'" u2="â" k="82"/><hkern u1="'" u2="á" k="82"/><hkern u1="'" u2="à" k="123"/><hkern u1="'" u2="Ý" k="-20"/><hkern u1="'" u2="Å" k="143"/><hkern u1="'" u2="Ä" k="143"/><hkern u1="'" u2="Ã" k="143"/><hkern u1="'" u2="Â" k="143"/><hkern u1="'" u2="Á" k="143"/><hkern u1="'" u2="À" k="143"/><hkern u1="'" u2="u" k="61"/><hkern u1="'" u2="s" k="61"/><hkern u1="'" u2="r" k="61"/><hkern u1="'" u2="q" k="123"/><hkern u1="'" u2="p" k="61"/><hkern u1="'" u2="o" k="123"/><hkern u1="'" u2="n" k="61"/><hkern u1="'" u2="m" k="61"/><hkern u1="'" u2="g" k="61"/><hkern u1="'" u2="e" k="123"/><hkern u1="'" u2="d" k="123"/><hkern u1="'" u2="c" k="123"/><hkern u1="'" u2="a" k="82"/><hkern u1="'" u2="Y" k="-20"/><hkern u1="'" u2="W" k="-41"/><hkern u1="'" u2="V" k="-41"/><hkern u1="'" u2="T" k="-41"/><hkern u1="'" u2="A" k="143"/><hkern u1="(" u2="J" k="-184"/><hkern u1="," u2="Ÿ" k="123"/><hkern u1="," u2="Œ" k="102"/><hkern u1="," u2="Ý" k="123"/><hkern u1="," u2="Ü" k="41"/><hkern u1="," u2="Û" k="41"/><hkern u1="," u2="Ú" k="41"/><hkern u1="," u2="Ù" k="41"/><hkern u1="," u2="Ø" k="102"/><hkern u1="," u2="Ö" k="102"/><hkern u1="," u2="Õ" k="102"/><hkern u1="," u2="Ô" k="102"/><hkern u1="," u2="Ó" k="102"/><hkern u1="," u2="Ò" k="102"/><hkern u1="," u2="Ç" k="102"/><hkern u1="," u2="Y" k="123"/><hkern u1="," u2="W" k="123"/><hkern u1="," u2="V" k="123"/><hkern u1="," u2="U" k="41"/><hkern u1="," u2="T" k="143"/><hkern u1="," u2="Q" k="102"/><hkern u1="," u2="O" k="102"/><hkern u1="," u2="G" k="102"/><hkern u1="," u2="C" k="102"/><hkern u1="-" u2="T" k="82"/><hkern u1="." u2="Ÿ" k="123"/><hkern u1="." u2="Œ" k="102"/><hkern u1="." u2="Ý" k="123"/><hkern u1="." u2="Ü" k="41"/><hkern u1="." u2="Û" k="41"/><hkern u1="." u2="Ú" k="41"/><hkern u1="." u2="Ù" k="41"/><hkern u1="." u2="Ø" k="102"/><hkern u1="." u2="Ö" k="102"/><hkern u1="." u2="Õ" k="102"/><hkern u1="." u2="Ô" k="102"/><hkern u1="." u2="Ó" k="102"/><hkern u1="." u2="Ò" k="102"/><hkern u1="." u2="Ç" k="102"/><hkern u1="." u2="Y" k="123"/><hkern u1="." u2="W" k="123"/><hkern u1="." u2="V" k="123"/><hkern u1="." u2="U" k="41"/><hkern u1="." u2="T" k="143"/><hkern u1="." u2="Q" k="102"/><hkern u1="." u2="O" k="102"/><hkern u1="." u2="G" k="102"/><hkern u1="." u2="C" k="102"/><hkern u1="A" u2="”" k="143"/><hkern u1="A" u2="’" k="143"/><hkern u1="A" u2="Ÿ" k="123"/><hkern u1="A" u2="Œ" k="41"/><hkern u1="A" u2="Ý" k="123"/><hkern u1="A" u2="Ø" k="41"/><hkern u1="A" u2="Ö" k="41"/><hkern u1="A" u2="Õ" k="41"/><hkern u1="A" u2="Ô" k="41"/><hkern u1="A" u2="Ó" k="41"/><hkern u1="A" u2="Ò" k="41"/><hkern u1="A" u2="Ç" k="41"/><hkern u1="A" u2="Y" k="123"/><hkern u1="A" u2="W" k="82"/><hkern u1="A" u2="V" k="82"/><hkern u1="A" u2="T" k="143"/><hkern u1="A" u2="Q" k="41"/><hkern u1="A" u2="O" k="41"/><hkern u1="A" u2="J" k="-266"/><hkern u1="A" u2="G" k="41"/><hkern u1="A" u2="C" k="41"/><hkern u1="A" u2="'" k="143"/><hkern u1="A" u2="&quot;" k="143"/><hkern u1="B" u2="„" k="82"/><hkern u1="B" u2="‚" k="82"/><hkern u1="B" u2="Ÿ" k="20"/><hkern u1="B" u2="Ý" k="20"/><hkern u1="B" u2="Å" k="41"/><hkern u1="B" u2="Ä" k="41"/><hkern u1="B" u2="Ã" k="41"/><hkern u1="B" u2="Â" k="41"/><hkern u1="B" u2="Á" k="41"/><hkern u1="B" u2="À" k="41"/><hkern u1="B" u2="Z" k="20"/><hkern u1="B" u2="Y" k="20"/><hkern u1="B" u2="X" k="41"/><hkern u1="B" u2="W" k="20"/><hkern u1="B" u2="V" k="20"/><hkern u1="B" u2="T" k="61"/><hkern u1="B" u2="A" k="41"/><hkern u1="B" u2="." k="82"/><hkern u1="B" u2="," k="82"/><hkern u1="C" u2="Œ" k="41"/><hkern u1="C" u2="Ø" k="41"/><hkern u1="C" u2="Ö" k="41"/><hkern u1="C" u2="Õ" k="41"/><hkern u1="C" u2="Ô" k="41"/><hkern u1="C" u2="Ó" k="41"/><hkern u1="C" u2="Ò" k="41"/><hkern u1="C" u2="Ç" k="41"/><hkern u1="C" u2="Q" k="41"/><hkern u1="C" u2="O" k="41"/><hkern u1="C" u2="G" k="41"/><hkern u1="C" u2="C" k="41"/><hkern u1="D" u2="„" k="82"/><hkern u1="D" u2="‚" k="82"/><hkern u1="D" u2="Ÿ" k="20"/><hkern u1="D" u2="Ý" k="20"/><hkern u1="D" u2="Å" k="41"/><hkern u1="D" u2="Ä" k="41"/><hkern u1="D" u2="Ã" k="41"/><hkern u1="D" u2="Â" k="41"/><hkern u1="D" u2="Á" k="41"/><hkern u1="D" u2="À" k="41"/><hkern u1="D" u2="Z" k="20"/><hkern u1="D" u2="Y" k="20"/><hkern u1="D" u2="X" k="41"/><hkern u1="D" u2="W" k="20"/><hkern u1="D" u2="V" k="20"/><hkern u1="D" u2="T" k="61"/><hkern u1="D" u2="A" k="41"/><hkern u1="D" u2="." k="82"/><hkern u1="D" u2="," k="82"/><hkern u1="E" u2="J" k="-123"/><hkern u1="F" u2="„" k="123"/><hkern u1="F" u2="‚" k="123"/><hkern u1="F" u2="Å" k="41"/><hkern u1="F" u2="Ä" k="41"/><hkern u1="F" u2="Ã" k="41"/><hkern u1="F" u2="Â" k="41"/><hkern u1="F" u2="Á" k="41"/><hkern u1="F" u2="À" k="41"/><hkern u1="F" u2="A" k="41"/><hkern u1="F" u2="?" k="-41"/><hkern u1="F" u2="." k="123"/><hkern u1="F" u2="," k="123"/><hkern u1="K" u2="Œ" k="41"/><hkern u1="K" u2="Ø" k="41"/><hkern u1="K" u2="Ö" k="41"/><hkern u1="K" u2="Õ" k="41"/><hkern u1="K" u2="Ô" k="41"/><hkern u1="K" u2="Ó" k="41"/><hkern u1="K" u2="Ò" k="41"/><hkern u1="K" u2="Ç" k="41"/><hkern u1="K" u2="Q" k="41"/><hkern u1="K" u2="O" k="41"/><hkern u1="K" u2="G" k="41"/><hkern u1="K" u2="C" k="41"/><hkern u1="L" u2="”" k="164"/><hkern u1="L" u2="’" k="164"/><hkern u1="L" u2="Ÿ" k="61"/><hkern u1="L" u2="Œ" k="41"/><hkern u1="L" u2="Ý" k="61"/><hkern u1="L" u2="Ü" k="20"/><hkern u1="L" u2="Û" k="20"/><hkern u1="L" u2="Ú" k="20"/><hkern u1="L" u2="Ù" k="20"/><hkern u1="L" u2="Ø" k="41"/><hkern u1="L" u2="Ö" k="41"/><hkern u1="L" u2="Õ" k="41"/><hkern u1="L" u2="Ô" k="41"/><hkern u1="L" u2="Ó" k="41"/><hkern u1="L" u2="Ò" k="41"/><hkern u1="L" u2="Ç" k="41"/><hkern u1="L" u2="Y" k="61"/><hkern u1="L" u2="W" k="41"/><hkern u1="L" u2="V" k="41"/><hkern u1="L" u2="U" k="20"/><hkern u1="L" u2="T" k="41"/><hkern u1="L" u2="Q" k="41"/><hkern u1="L" u2="O" k="41"/><hkern u1="L" u2="G" k="41"/><hkern u1="L" u2="C" k="41"/><hkern u1="L" u2="'" k="164"/><hkern u1="L" u2="&quot;" k="164"/><hkern u1="O" u2="„" k="82"/><hkern u1="O" u2="‚" k="82"/><hkern u1="O" u2="Ÿ" k="20"/><hkern u1="O" u2="Ý" k="20"/><hkern u1="O" u2="Å" k="41"/><hkern u1="O" u2="Ä" k="41"/><hkern u1="O" u2="Ã" k="41"/><hkern u1="O" u2="Â" k="41"/><hkern u1="O" u2="Á" k="41"/><hkern u1="O" u2="À" k="41"/><hkern u1="O" u2="Z" k="20"/><hkern u1="O" u2="Y" k="20"/><hkern u1="O" u2="X" k="41"/><hkern u1="O" u2="W" k="20"/><hkern u1="O" u2="V" k="20"/><hkern u1="O" u2="T" k="61"/><hkern u1="O" u2="A" k="41"/><hkern u1="O" u2="." k="82"/><hkern u1="O" u2="," k="82"/><hkern u1="P" u2="„" k="266"/><hkern u1="P" u2="‚" k="266"/><hkern u1="P" u2="Å" k="102"/><hkern u1="P" u2="Ä" k="102"/><hkern u1="P" u2="Ã" k="102"/><hkern u1="P" u2="Â" k="102"/><hkern u1="P" u2="Á" k="102"/><hkern u1="P" u2="À" k="102"/><hkern u1="P" u2="Z" k="20"/><hkern u1="P" u2="X" k="41"/><hkern u1="P" u2="A" k="102"/><hkern u1="P" u2="." k="266"/><hkern u1="P" u2="," k="266"/><hkern u1="Q" u2="„" k="82"/><hkern u1="Q" u2="‚" k="82"/><hkern u1="Q" u2="Ÿ" k="20"/><hkern u1="Q" u2="Ý" k="20"/><hkern u1="Q" u2="Å" k="41"/><hkern u1="Q" u2="Ä" k="41"/><hkern u1="Q" u2="Ã" k="41"/><hkern u1="Q" u2="Â" k="41"/><hkern u1="Q" u2="Á" k="41"/><hkern u1="Q" u2="À" k="41"/><hkern u1="Q" u2="Z" k="20"/><hkern u1="Q" u2="Y" k="20"/><hkern u1="Q" u2="X" k="41"/><hkern u1="Q" u2="W" k="20"/><hkern u1="Q" u2="V" k="20"/><hkern u1="Q" u2="T" k="61"/><hkern u1="Q" u2="A" k="41"/><hkern u1="Q" u2="." k="82"/><hkern u1="Q" u2="," k="82"/><hkern u1="T" u2="„" k="123"/><hkern u1="T" u2="‚" k="123"/><hkern u1="T" u2="—" k="82"/><hkern u1="T" u2="–" k="82"/><hkern u1="T" u2="œ" k="143"/><hkern u1="T" u2="Œ" k="41"/><hkern u1="T" u2="ý" k="41"/><hkern u1="T" u2="ü" k="102"/><hkern u1="T" u2="û" k="102"/><hkern u1="T" u2="ú" k="102"/><hkern u1="T" u2="ù" k="102"/><hkern u1="T" u2="ø" k="143"/><hkern u1="T" u2="ö" k="143"/><hkern u1="T" u2="õ" k="143"/><hkern u1="T" u2="ô" k="143"/><hkern u1="T" u2="ó" k="143"/><hkern u1="T" u2="ò" k="143"/><hkern u1="T" u2="ë" k="143"/><hkern u1="T" u2="ê" k="143"/><hkern u1="T" u2="é" k="143"/><hkern u1="T" u2="è" k="143"/><hkern u1="T" u2="ç" k="143"/><hkern u1="T" u2="æ" k="164"/><hkern u1="T" u2="å" k="164"/><hkern u1="T" u2="ä" k="164"/><hkern u1="T" u2="ã" k="164"/><hkern u1="T" u2="â" k="164"/><hkern u1="T" u2="á" k="164"/><hkern u1="T" u2="à" k="143"/><hkern u1="T" u2="Ø" k="41"/><hkern u1="T" u2="Ö" k="41"/><hkern u1="T" u2="Õ" k="41"/><hkern u1="T" u2="Ô" k="41"/><hkern u1="T" u2="Ó" k="41"/><hkern u1="T" u2="Ò" k="41"/><hkern u1="T" u2="Ç" k="41"/><hkern u1="T" u2="Å" k="143"/><hkern u1="T" u2="Ä" k="143"/><hkern u1="T" u2="Ã" k="143"/><hkern u1="T" u2="Â" k="143"/><hkern u1="T" u2="Á" k="143"/><hkern u1="T" u2="À" k="143"/><hkern u1="T" u2="z" k="82"/><hkern u1="T" u2="y" k="41"/><hkern u1="T" u2="x" k="41"/><hkern u1="T" u2="w" k="41"/><hkern u1="T" u2="v" k="41"/><hkern u1="T" u2="u" k="102"/><hkern u1="T" u2="s" k="123"/><hkern u1="T" u2="r" k="102"/><hkern u1="T" u2="q" k="143"/><hkern u1="T" u2="p" k="102"/><hkern u1="T" u2="o" k="143"/><hkern u1="T" u2="n" k="102"/><hkern u1="T" u2="m" k="102"/><hkern u1="T" u2="g" k="143"/><hkern u1="T" u2="e" k="143"/><hkern u1="T" u2="d" k="143"/><hkern u1="T" u2="c" k="143"/><hkern u1="T" u2="a" k="164"/><hkern u1="T" u2="T" k="-41"/><hkern u1="T" u2="Q" k="41"/><hkern u1="T" u2="O" k="41"/><hkern u1="T" u2="G" k="41"/><hkern u1="T" u2="C" k="41"/><hkern u1="T" u2="A" k="143"/><hkern u1="T" u2="?" k="-41"/><hkern u1="T" u2="." k="123"/><hkern u1="T" u2="-" k="82"/><hkern u1="T" u2="," k="123"/><hkern u1="U" u2="„" k="41"/><hkern u1="U" u2="‚" k="41"/><hkern u1="U" u2="Å" k="20"/><hkern u1="U" u2="Ä" k="20"/><hkern u1="U" u2="Ã" k="20"/><hkern u1="U" u2="Â" k="20"/><hkern u1="U" u2="Á" k="20"/><hkern u1="U" u2="À" k="20"/><hkern u1="U" u2="A" k="20"/><hkern u1="U" u2="." k="41"/><hkern u1="U" u2="," k="41"/><hkern u1="V" u2="„" k="102"/><hkern u1="V" u2="‚" k="102"/><hkern u1="V" u2="œ" k="41"/><hkern u1="V" u2="Œ" k="20"/><hkern u1="V" u2="ü" k="20"/><hkern u1="V" u2="û" k="20"/><hkern u1="V" u2="ú" k="20"/><hkern u1="V" u2="ù" k="20"/><hkern u1="V" u2="ø" k="41"/><hkern u1="V" u2="ö" k="41"/><hkern u1="V" u2="õ" k="41"/><hkern u1="V" u2="ô" k="41"/><hkern u1="V" u2="ó" k="41"/><hkern u1="V" u2="ò" k="41"/><hkern u1="V" u2="ë" k="41"/><hkern u1="V" u2="ê" k="41"/><hkern u1="V" u2="é" k="41"/><hkern u1="V" u2="è" k="41"/><hkern u1="V" u2="ç" k="41"/><hkern u1="V" u2="æ" k="41"/><hkern u1="V" u2="å" k="41"/><hkern u1="V" u2="ä" k="41"/><hkern u1="V" u2="ã" k="41"/><hkern u1="V" u2="â" k="41"/><hkern u1="V" u2="á" k="41"/><hkern u1="V" u2="à" k="41"/><hkern u1="V" u2="Ø" k="20"/><hkern u1="V" u2="Ö" k="20"/><hkern u1="V" u2="Õ" k="20"/><hkern u1="V" u2="Ô" k="20"/><hkern u1="V" u2="Ó" k="20"/><hkern u1="V" u2="Ò" k="20"/><hkern u1="V" u2="Ç" k="20"/><hkern u1="V" u2="Å" k="82"/><hkern u1="V" u2="Ä" k="82"/><hkern u1="V" u2="Ã" k="82"/><hkern u1="V" u2="Â" k="82"/><hkern u1="V" u2="Á" k="82"/><hkern u1="V" u2="À" k="82"/><hkern u1="V" u2="u" k="20"/><hkern u1="V" u2="s" k="20"/><hkern u1="V" u2="r" k="20"/><hkern u1="V" u2="q" k="41"/><hkern u1="V" u2="p" k="20"/><hkern u1="V" u2="o" k="41"/><hkern u1="V" u2="n" k="20"/><hkern u1="V" u2="m" k="20"/><hkern u1="V" u2="g" k="20"/><hkern u1="V" u2="e" k="41"/><hkern u1="V" u2="d" k="41"/><hkern u1="V" u2="c" k="41"/><hkern u1="V" u2="a" k="41"/><hkern u1="V" u2="Q" k="20"/><hkern u1="V" u2="O" k="20"/><hkern u1="V" u2="G" k="20"/><hkern u1="V" u2="C" k="20"/><hkern u1="V" u2="A" k="82"/><hkern u1="V" u2="?" k="-41"/><hkern u1="V" u2="." k="102"/><hkern u1="V" u2="," k="102"/><hkern u1="W" u2="„" k="102"/><hkern u1="W" u2="‚" k="102"/><hkern u1="W" u2="œ" k="41"/><hkern u1="W" u2="Œ" k="20"/><hkern u1="W" u2="ü" k="20"/><hkern u1="W" u2="û" k="20"/><hkern u1="W" u2="ú" k="20"/><hkern u1="W" u2="ù" k="20"/><hkern u1="W" u2="ø" k="41"/><hkern u1="W" u2="ö" k="41"/><hkern u1="W" u2="õ" k="41"/><hkern u1="W" u2="ô" k="41"/><hkern u1="W" u2="ó" k="41"/><hkern u1="W" u2="ò" k="41"/><hkern u1="W" u2="ë" k="41"/><hkern u1="W" u2="ê" k="41"/><hkern u1="W" u2="é" k="41"/><hkern u1="W" u2="è" k="41"/><hkern u1="W" u2="ç" k="41"/><hkern u1="W" u2="æ" k="41"/><hkern u1="W" u2="å" k="41"/><hkern u1="W" u2="ä" k="41"/><hkern u1="W" u2="ã" k="41"/><hkern u1="W" u2="â" k="41"/><hkern u1="W" u2="á" k="41"/><hkern u1="W" u2="à" k="41"/><hkern u1="W" u2="Ø" k="20"/><hkern u1="W" u2="Ö" k="20"/><hkern u1="W" u2="Õ" k="20"/><hkern u1="W" u2="Ô" k="20"/><hkern u1="W" u2="Ó" k="20"/><hkern u1="W" u2="Ò" k="20"/><hkern u1="W" u2="Ç" k="20"/><hkern u1="W" u2="Å" k="82"/><hkern u1="W" u2="Ä" k="82"/><hkern u1="W" u2="Ã" k="82"/><hkern u1="W" u2="Â" k="82"/><hkern u1="W" u2="Á" k="82"/><hkern u1="W" u2="À" k="82"/><hkern u1="W" u2="u" k="20"/><hkern u1="W" u2="s" k="20"/><hkern u1="W" u2="r" k="20"/><hkern u1="W" u2="q" k="41"/><hkern u1="W" u2="p" k="20"/><hkern u1="W" u2="o" k="41"/><hkern u1="W" u2="n" k="20"/><hkern u1="W" u2="m" k="20"/><hkern u1="W" u2="g" k="20"/><hkern u1="W" u2="e" k="41"/><hkern u1="W" u2="d" k="41"/><hkern u1="W" u2="c" k="41"/><hkern u1="W" u2="a" k="41"/><hkern u1="W" u2="Q" k="20"/><hkern u1="W" u2="O" k="20"/><hkern u1="W" u2="G" k="20"/><hkern u1="W" u2="C" k="20"/><hkern u1="W" u2="A" k="82"/><hkern u1="W" u2="?" k="-41"/><hkern u1="W" u2="." k="102"/><hkern u1="W" u2="," k="102"/><hkern u1="X" u2="Œ" k="41"/><hkern u1="X" u2="Ø" k="41"/><hkern u1="X" u2="Ö" k="41"/><hkern u1="X" u2="Õ" k="41"/><hkern u1="X" u2="Ô" k="41"/><hkern u1="X" u2="Ó" k="41"/><hkern u1="X" u2="Ò" k="41"/><hkern u1="X" u2="Ç" k="41"/><hkern u1="X" u2="Q" k="41"/><hkern u1="X" u2="O" k="41"/><hkern u1="X" u2="G" k="41"/><hkern u1="X" u2="C" k="41"/><hkern u1="Y" u2="„" k="123"/><hkern u1="Y" u2="‚" k="123"/><hkern u1="Y" u2="œ" k="102"/><hkern u1="Y" u2="Œ" k="41"/><hkern u1="Y" u2="ü" k="61"/><hkern u1="Y" u2="û" k="61"/><hkern u1="Y" u2="ú" k="61"/><hkern u1="Y" u2="ù" k="61"/><hkern u1="Y" u2="ø" k="102"/><hkern u1="Y" u2="ö" k="102"/><hkern u1="Y" u2="õ" k="102"/><hkern u1="Y" u2="ô" k="102"/><hkern u1="Y" u2="ó" k="102"/><hkern u1="Y" u2="ò" k="102"/><hkern u1="Y" u2="ë" k="102"/><hkern u1="Y" u2="ê" k="102"/><hkern u1="Y" u2="é" k="102"/><hkern u1="Y" u2="è" k="102"/><hkern u1="Y" u2="ç" k="102"/><hkern u1="Y" u2="æ" k="102"/><hkern u1="Y" u2="å" k="102"/><hkern u1="Y" u2="ä" k="102"/><hkern u1="Y" u2="ã" k="102"/><hkern u1="Y" u2="â" k="102"/><hkern u1="Y" u2="á" k="102"/><hkern u1="Y" u2="à" k="102"/><hkern u1="Y" u2="Ø" k="41"/><hkern u1="Y" u2="Ö" k="41"/><hkern u1="Y" u2="Õ" k="41"/><hkern u1="Y" u2="Ô" k="41"/><hkern u1="Y" u2="Ó" k="41"/><hkern u1="Y" u2="Ò" k="41"/><hkern u1="Y" u2="Ç" k="41"/><hkern u1="Y" u2="Å" k="123"/><hkern u1="Y" u2="Ä" k="123"/><hkern u1="Y" u2="Ã" k="123"/><hkern u1="Y" u2="Â" k="123"/><hkern u1="Y" u2="Á" k="123"/><hkern u1="Y" u2="À" k="123"/><hkern u1="Y" u2="z" k="41"/><hkern u1="Y" u2="u" k="61"/><hkern u1="Y" u2="s" k="82"/><hkern u1="Y" u2="r" k="61"/><hkern u1="Y" u2="q" k="102"/><hkern u1="Y" u2="p" k="61"/><hkern u1="Y" u2="o" k="102"/><hkern u1="Y" u2="n" k="61"/><hkern u1="Y" u2="m" k="61"/><hkern u1="Y" u2="g" k="41"/><hkern u1="Y" u2="e" k="102"/><hkern u1="Y" u2="d" k="102"/><hkern u1="Y" u2="c" k="102"/><hkern u1="Y" u2="a" k="102"/><hkern u1="Y" u2="Q" k="41"/><hkern u1="Y" u2="O" k="41"/><hkern u1="Y" u2="G" k="41"/><hkern u1="Y" u2="C" k="41"/><hkern u1="Y" u2="A" k="123"/><hkern u1="Y" u2="?" k="-41"/><hkern u1="Y" u2="." k="123"/><hkern u1="Y" u2="," k="123"/><hkern u1="Z" u2="Œ" k="20"/><hkern u1="Z" u2="Ø" k="20"/><hkern u1="Z" u2="Ö" k="20"/><hkern u1="Z" u2="Õ" k="20"/><hkern u1="Z" u2="Ô" k="20"/><hkern u1="Z" u2="Ó" k="20"/><hkern u1="Z" u2="Ò" k="20"/><hkern u1="Z" u2="Ç" k="20"/><hkern u1="Z" u2="Q" k="20"/><hkern u1="Z" u2="O" k="20"/><hkern u1="Z" u2="G" k="20"/><hkern u1="Z" u2="C" k="20"/><hkern u1="[" u2="J" k="-184"/><hkern u1="a" u2="”" k="20"/><hkern u1="a" u2="’" k="20"/><hkern u1="a" u2="'" k="20"/><hkern u1="a" u2="&quot;" k="20"/><hkern u1="b" u2="”" k="20"/><hkern u1="b" u2="’" k="20"/><hkern u1="b" u2="ý" k="41"/><hkern u1="b" u2="z" k="20"/><hkern u1="b" u2="y" k="41"/><hkern u1="b" u2="x" k="41"/><hkern u1="b" u2="w" k="41"/><hkern u1="b" u2="v" k="41"/><hkern u1="b" u2="'" k="20"/><hkern u1="b" u2="&quot;" k="20"/><hkern u1="c" u2="”" k="-41"/><hkern u1="c" u2="’" k="-41"/><hkern u1="c" u2="'" k="-41"/><hkern u1="c" u2="&quot;" k="-41"/><hkern u1="e" u2="”" k="20"/><hkern u1="e" u2="’" k="20"/><hkern u1="e" u2="ý" k="41"/><hkern u1="e" u2="z" k="20"/><hkern u1="e" u2="y" k="41"/><hkern u1="e" u2="x" k="41"/><hkern u1="e" u2="w" k="41"/><hkern u1="e" u2="v" k="41"/><hkern u1="e" u2="'" k="20"/><hkern u1="e" u2="&quot;" k="20"/><hkern u1="f" u2="”" k="-123"/><hkern u1="f" u2="’" k="-123"/><hkern u1="f" u2="'" k="-123"/><hkern u1="f" u2="&quot;" k="-123"/><hkern u1="h" u2="”" k="20"/><hkern u1="h" u2="’" k="20"/><hkern u1="h" u2="'" k="20"/><hkern u1="h" u2="&quot;" k="20"/><hkern u1="k" u2="œ" k="41"/><hkern u1="k" u2="ø" k="41"/><hkern u1="k" u2="ö" k="41"/><hkern u1="k" u2="õ" k="41"/><hkern u1="k" u2="ô" k="41"/><hkern u1="k" u2="ó" k="41"/><hkern u1="k" u2="ò" k="41"/><hkern u1="k" u2="ë" k="41"/><hkern u1="k" u2="ê" k="41"/><hkern u1="k" u2="é" k="41"/><hkern u1="k" u2="è" k="41"/><hkern u1="k" u2="ç" k="41"/><hkern u1="k" u2="à" k="41"/><hkern u1="k" u2="q" k="41"/><hkern u1="k" u2="o" k="41"/><hkern u1="k" u2="e" k="41"/><hkern u1="k" u2="d" k="41"/><hkern u1="k" u2="c" k="41"/><hkern u1="m" u2="”" k="20"/><hkern u1="m" u2="’" k="20"/><hkern u1="m" u2="'" k="20"/><hkern u1="m" u2="&quot;" k="20"/><hkern u1="n" u2="”" k="20"/><hkern u1="n" u2="’" k="20"/><hkern u1="n" u2="'" k="20"/><hkern u1="n" u2="&quot;" k="20"/><hkern u1="o" u2="”" k="20"/><hkern u1="o" u2="’" k="20"/><hkern u1="o" u2="ý" k="41"/><hkern u1="o" u2="z" k="20"/><hkern u1="o" u2="y" k="41"/><hkern u1="o" u2="x" k="41"/><hkern u1="o" u2="w" k="41"/><hkern u1="o" u2="v" k="41"/><hkern u1="o" u2="'" k="20"/><hkern u1="o" u2="&quot;" k="20"/><hkern u1="p" u2="”" k="20"/><hkern u1="p" u2="’" k="20"/><hkern u1="p" u2="ý" k="41"/><hkern u1="p" u2="z" k="20"/><hkern u1="p" u2="y" k="41"/><hkern u1="p" u2="x" k="41"/><hkern u1="p" u2="w" k="41"/><hkern u1="p" u2="v" k="41"/><hkern u1="p" u2="'" k="20"/><hkern u1="p" u2="&quot;" k="20"/><hkern u1="r" u2="”" k="-82"/><hkern u1="r" u2="’" k="-82"/><hkern u1="r" u2="œ" k="41"/><hkern u1="r" u2="ø" k="41"/><hkern u1="r" u2="ö" k="41"/><hkern u1="r" u2="õ" k="41"/><hkern u1="r" u2="ô" k="41"/><hkern u1="r" u2="ó" k="41"/><hkern u1="r" u2="ò" k="41"/><hkern u1="r" u2="ë" k="41"/><hkern u1="r" u2="ê" k="41"/><hkern u1="r" u2="é" k="41"/><hkern u1="r" u2="è" k="41"/><hkern u1="r" u2="ç" k="41"/><hkern u1="r" u2="æ" k="41"/><hkern u1="r" u2="å" k="41"/><hkern u1="r" u2="ä" k="41"/><hkern u1="r" u2="ã" k="41"/><hkern u1="r" u2="â" k="41"/><hkern u1="r" u2="á" k="41"/><hkern u1="r" u2="à" k="41"/><hkern u1="r" u2="q" k="41"/><hkern u1="r" u2="o" k="41"/><hkern u1="r" u2="g" k="20"/><hkern u1="r" u2="e" k="41"/><hkern u1="r" u2="d" k="41"/><hkern u1="r" u2="c" k="41"/><hkern u1="r" u2="a" k="41"/><hkern u1="r" u2="'" k="-82"/><hkern u1="r" u2="&quot;" k="-82"/><hkern u1="t" u2="”" k="-41"/><hkern u1="t" u2="’" k="-41"/><hkern u1="t" u2="'" k="-41"/><hkern u1="t" u2="&quot;" k="-41"/><hkern u1="v" u2="„" k="82"/><hkern u1="v" u2="”" k="-82"/><hkern u1="v" u2="‚" k="82"/><hkern u1="v" u2="’" k="-82"/><hkern u1="v" u2="?" k="-41"/><hkern u1="v" u2="." k="82"/><hkern u1="v" u2="," k="82"/><hkern u1="v" u2="'" k="-82"/><hkern u1="v" u2="&quot;" k="-82"/><hkern u1="w" u2="„" k="82"/><hkern u1="w" u2="”" k="-82"/><hkern u1="w" u2="‚" k="82"/><hkern u1="w" u2="’" k="-82"/><hkern u1="w" u2="?" k="-41"/><hkern u1="w" u2="." k="82"/><hkern u1="w" u2="," k="82"/><hkern u1="w" u2="'" k="-82"/><hkern u1="w" u2="&quot;" k="-82"/><hkern u1="x" u2="œ" k="41"/><hkern u1="x" u2="ø" k="41"/><hkern u1="x" u2="ö" k="41"/><hkern u1="x" u2="õ" k="41"/><hkern u1="x" u2="ô" k="41"/><hkern u1="x" u2="ó" k="41"/><hkern u1="x" u2="ò" k="41"/><hkern u1="x" u2="ë" k="41"/><hkern u1="x" u2="ê" k="41"/><hkern u1="x" u2="é" k="41"/><hkern u1="x" u2="è" k="41"/><hkern u1="x" u2="ç" k="41"/><hkern u1="x" u2="à" k="41"/><hkern u1="x" u2="q" k="41"/><hkern u1="x" u2="o" k="41"/><hkern u1="x" u2="e" k="41"/><hkern u1="x" u2="d" k="41"/><hkern u1="x" u2="c" k="41"/><hkern u1="y" u2="„" k="82"/><hkern u1="y" u2="”" k="-82"/><hkern u1="y" u2="‚" k="82"/><hkern u1="y" u2="’" k="-82"/><hkern u1="y" u2="?" k="-41"/><hkern u1="y" u2="." k="82"/><hkern u1="y" u2="," k="82"/><hkern u1="y" u2="'" k="-82"/><hkern u1="y" u2="&quot;" k="-82"/><hkern u1="{" u2="J" k="-184"/><hkern u1="À" u2="”" k="143"/><hkern u1="À" u2="’" k="143"/><hkern u1="À" u2="Ÿ" k="123"/><hkern u1="À" u2="Œ" k="41"/><hkern u1="À" u2="Ý" k="123"/><hkern u1="À" u2="Ø" k="41"/><hkern u1="À" u2="Ö" k="41"/><hkern u1="À" u2="Õ" k="41"/><hkern u1="À" u2="Ô" k="41"/><hkern u1="À" u2="Ó" k="41"/><hkern u1="À" u2="Ò" k="41"/><hkern u1="À" u2="Ç" k="41"/><hkern u1="À" u2="Y" k="123"/><hkern u1="À" u2="W" k="82"/><hkern u1="À" u2="V" k="82"/><hkern u1="À" u2="T" k="143"/><hkern u1="À" u2="Q" k="41"/><hkern u1="À" u2="O" k="41"/><hkern u1="À" u2="J" k="-266"/><hkern u1="À" u2="G" k="41"/><hkern u1="À" u2="C" k="41"/><hkern u1="À" u2="'" k="143"/><hkern u1="À" u2="&quot;" k="143"/><hkern u1="Á" u2="”" k="143"/><hkern u1="Á" u2="’" k="143"/><hkern u1="Á" u2="Ÿ" k="123"/><hkern u1="Á" u2="Œ" k="41"/><hkern u1="Á" u2="Ý" k="123"/><hkern u1="Á" u2="Ø" k="41"/><hkern u1="Á" u2="Ö" k="41"/><hkern u1="Á" u2="Õ" k="41"/><hkern u1="Á" u2="Ô" k="41"/><hkern u1="Á" u2="Ó" k="41"/><hkern u1="Á" u2="Ò" k="41"/><hkern u1="Á" u2="Ç" k="41"/><hkern u1="Á" u2="Y" k="123"/><hkern u1="Á" u2="W" k="82"/><hkern u1="Á" u2="V" k="82"/><hkern u1="Á" u2="T" k="143"/><hkern u1="Á" u2="Q" k="41"/><hkern u1="Á" u2="O" k="41"/><hkern u1="Á" u2="J" k="-266"/><hkern u1="Á" u2="G" k="41"/><hkern u1="Á" u2="C" k="41"/><hkern u1="Á" u2="'" k="143"/><hkern u1="Á" u2="&quot;" k="143"/><hkern u1="Â" u2="”" k="143"/><hkern u1="Â" u2="’" k="143"/><hkern u1="Â" u2="Ÿ" k="123"/><hkern u1="Â" u2="Œ" k="41"/><hkern u1="Â" u2="Ý" k="123"/><hkern u1="Â" u2="Ø" k="41"/><hkern u1="Â" u2="Ö" k="41"/><hkern u1="Â" u2="Õ" k="41"/><hkern u1="Â" u2="Ô" k="41"/><hkern u1="Â" u2="Ó" k="41"/><hkern u1="Â" u2="Ò" k="41"/><hkern u1="Â" u2="Ç" k="41"/><hkern u1="Â" u2="Y" k="123"/><hkern u1="Â" u2="W" k="82"/><hkern u1="Â" u2="V" k="82"/><hkern u1="Â" u2="T" k="143"/><hkern u1="Â" u2="Q" k="41"/><hkern u1="Â" u2="O" k="41"/><hkern u1="Â" u2="J" k="-266"/><hkern u1="Â" u2="G" k="41"/><hkern u1="Â" u2="C" k="41"/><hkern u1="Â" u2="'" k="143"/><hkern u1="Â" u2="&quot;" k="143"/><hkern u1="Ã" u2="”" k="143"/><hkern u1="Ã" u2="’" k="143"/><hkern u1="Ã" u2="Ÿ" k="123"/><hkern u1="Ã" u2="Œ" k="41"/><hkern u1="Ã" u2="Ý" k="123"/><hkern u1="Ã" u2="Ø" k="41"/><hkern u1="Ã" u2="Ö" k="41"/><hkern u1="Ã" u2="Õ" k="41"/><hkern u1="Ã" u2="Ô" k="41"/><hkern u1="Ã" u2="Ó" k="41"/><hkern u1="Ã" u2="Ò" k="41"/><hkern u1="Ã" u2="Ç" k="41"/><hkern u1="Ã" u2="Y" k="123"/><hkern u1="Ã" u2="W" k="82"/><hkern u1="Ã" u2="V" k="82"/><hkern u1="Ã" u2="T" k="143"/><hkern u1="Ã" u2="Q" k="41"/><hkern u1="Ã" u2="O" k="41"/><hkern u1="Ã" u2="J" k="-266"/><hkern u1="Ã" u2="G" k="41"/><hkern u1="Ã" u2="C" k="41"/><hkern u1="Ã" u2="'" k="143"/><hkern u1="Ã" u2="&quot;" k="143"/><hkern u1="Ä" u2="”" k="143"/><hkern u1="Ä" u2="’" k="143"/><hkern u1="Ä" u2="Ÿ" k="123"/><hkern u1="Ä" u2="Œ" k="41"/><hkern u1="Ä" u2="Ý" k="123"/><hkern u1="Ä" u2="Ø" k="41"/><hkern u1="Ä" u2="Ö" k="41"/><hkern u1="Ä" u2="Õ" k="41"/><hkern u1="Ä" u2="Ô" k="41"/><hkern u1="Ä" u2="Ó" k="41"/><hkern u1="Ä" u2="Ò" k="41"/><hkern u1="Ä" u2="Ç" k="41"/><hkern u1="Ä" u2="Y" k="123"/><hkern u1="Ä" u2="W" k="82"/><hkern u1="Ä" u2="V" k="82"/><hkern u1="Ä" u2="T" k="143"/><hkern u1="Ä" u2="Q" k="41"/><hkern u1="Ä" u2="O" k="41"/><hkern u1="Ä" u2="J" k="-266"/><hkern u1="Ä" u2="G" k="41"/><hkern u1="Ä" u2="C" k="41"/><hkern u1="Ä" u2="'" k="143"/><hkern u1="Ä" u2="&quot;" k="143"/><hkern u1="Å" u2="”" k="143"/><hkern u1="Å" u2="’" k="143"/><hkern u1="Å" u2="Ÿ" k="123"/><hkern u1="Å" u2="Œ" k="41"/><hkern u1="Å" u2="Ý" k="123"/><hkern u1="Å" u2="Ø" k="41"/><hkern u1="Å" u2="Ö" k="41"/><hkern u1="Å" u2="Õ" k="41"/><hkern u1="Å" u2="Ô" k="41"/><hkern u1="Å" u2="Ó" k="41"/><hkern u1="Å" u2="Ò" k="41"/><hkern u1="Å" u2="Ç" k="41"/><hkern u1="Å" u2="Y" k="123"/><hkern u1="Å" u2="W" k="82"/><hkern u1="Å" u2="V" k="82"/><hkern u1="Å" u2="T" k="143"/><hkern u1="Å" u2="Q" k="41"/><hkern u1="Å" u2="O" k="41"/><hkern u1="Å" u2="J" k="-266"/><hkern u1="Å" u2="G" k="41"/><hkern u1="Å" u2="C" k="41"/><hkern u1="Å" u2="'" k="143"/><hkern u1="Å" u2="&quot;" k="143"/><hkern u1="Æ" u2="J" k="-123"/><hkern u1="Ç" u2="Œ" k="41"/><hkern u1="Ç" u2="Ø" k="41"/><hkern u1="Ç" u2="Ö" k="41"/><hkern u1="Ç" u2="Õ" k="41"/><hkern u1="Ç" u2="Ô" k="41"/><hkern u1="Ç" u2="Ó" k="41"/><hkern u1="Ç" u2="Ò" k="41"/><hkern u1="Ç" u2="Ç" k="41"/><hkern u1="Ç" u2="Q" k="41"/><hkern u1="Ç" u2="O" k="41"/><hkern u1="Ç" u2="G" k="41"/><hkern u1="Ç" u2="C" k="41"/><hkern u1="È" u2="J" k="-123"/><hkern u1="É" u2="J" k="-123"/><hkern u1="Ê" u2="J" k="-123"/><hkern u1="Ë" u2="J" k="-123"/><hkern u1="Ð" u2="„" k="82"/><hkern u1="Ð" u2="‚" k="82"/><hkern u1="Ð" u2="Ÿ" k="20"/><hkern u1="Ð" u2="Ý" k="20"/><hkern u1="Ð" u2="Å" k="41"/><hkern u1="Ð" u2="Ä" k="41"/><hkern u1="Ð" u2="Ã" k="41"/><hkern u1="Ð" u2="Â" k="41"/><hkern u1="Ð" u2="Á" k="41"/><hkern u1="Ð" u2="À" k="41"/><hkern u1="Ð" u2="Z" k="20"/><hkern u1="Ð" u2="Y" k="20"/><hkern u1="Ð" u2="X" k="41"/><hkern u1="Ð" u2="W" k="20"/><hkern u1="Ð" u2="V" k="20"/><hkern u1="Ð" u2="T" k="61"/><hkern u1="Ð" u2="A" k="41"/><hkern u1="Ð" u2="." k="82"/><hkern u1="Ð" u2="," k="82"/><hkern u1="Ò" u2="„" k="82"/><hkern u1="Ò" u2="‚" k="82"/><hkern u1="Ò" u2="Ÿ" k="20"/><hkern u1="Ò" u2="Ý" k="20"/><hkern u1="Ò" u2="Å" k="41"/><hkern u1="Ò" u2="Ä" k="41"/><hkern u1="Ò" u2="Ã" k="41"/><hkern u1="Ò" u2="Â" k="41"/><hkern u1="Ò" u2="Á" k="41"/><hkern u1="Ò" u2="À" k="41"/><hkern u1="Ò" u2="Z" k="20"/><hkern u1="Ò" u2="Y" k="20"/><hkern u1="Ò" u2="X" k="41"/><hkern u1="Ò" u2="W" k="20"/><hkern u1="Ò" u2="V" k="20"/><hkern u1="Ò" u2="T" k="61"/><hkern u1="Ò" u2="A" k="41"/><hkern u1="Ò" u2="." k="82"/><hkern u1="Ò" u2="," k="82"/><hkern u1="Ó" u2="„" k="82"/><hkern u1="Ó" u2="‚" k="82"/><hkern u1="Ó" u2="Ÿ" k="20"/><hkern u1="Ó" u2="Ý" k="20"/><hkern u1="Ó" u2="Å" k="41"/><hkern u1="Ó" u2="Ä" k="41"/><hkern u1="Ó" u2="Ã" k="41"/><hkern u1="Ó" u2="Â" k="41"/><hkern u1="Ó" u2="Á" k="41"/><hkern u1="Ó" u2="À" k="41"/><hkern u1="Ó" u2="Z" k="20"/><hkern u1="Ó" u2="Y" k="20"/><hkern u1="Ó" u2="X" k="41"/><hkern u1="Ó" u2="W" k="20"/><hkern u1="Ó" u2="V" k="20"/><hkern u1="Ó" u2="T" k="61"/><hkern u1="Ó" u2="A" k="41"/><hkern u1="Ó" u2="." k="82"/><hkern u1="Ó" u2="," k="82"/><hkern u1="Ô" u2="„" k="82"/><hkern u1="Ô" u2="‚" k="82"/><hkern u1="Ô" u2="Ÿ" k="20"/><hkern u1="Ô" u2="Ý" k="20"/><hkern u1="Ô" u2="Å" k="41"/><hkern u1="Ô" u2="Ä" k="41"/><hkern u1="Ô" u2="Ã" k="41"/><hkern u1="Ô" u2="Â" k="41"/><hkern u1="Ô" u2="Á" k="41"/><hkern u1="Ô" u2="À" k="41"/><hkern u1="Ô" u2="Z" k="20"/><hkern u1="Ô" u2="Y" k="20"/><hkern u1="Ô" u2="X" k="41"/><hkern u1="Ô" u2="W" k="20"/><hkern u1="Ô" u2="V" k="20"/><hkern u1="Ô" u2="T" k="61"/><hkern u1="Ô" u2="A" k="41"/><hkern u1="Ô" u2="." k="82"/><hkern u1="Ô" u2="," k="82"/><hkern u1="Õ" u2="„" k="82"/><hkern u1="Õ" u2="‚" k="82"/><hkern u1="Õ" u2="Ÿ" k="20"/><hkern u1="Õ" u2="Ý" k="20"/><hkern u1="Õ" u2="Å" k="41"/><hkern u1="Õ" u2="Ä" k="41"/><hkern u1="Õ" u2="Ã" k="41"/><hkern u1="Õ" u2="Â" k="41"/><hkern u1="Õ" u2="Á" k="41"/><hkern u1="Õ" u2="À" k="41"/><hkern u1="Õ" u2="Z" k="20"/><hkern u1="Õ" u2="Y" k="20"/><hkern u1="Õ" u2="X" k="41"/><hkern u1="Õ" u2="W" k="20"/><hkern u1="Õ" u2="V" k="20"/><hkern u1="Õ" u2="T" k="61"/><hkern u1="Õ" u2="A" k="41"/><hkern u1="Õ" u2="." k="82"/><hkern u1="Õ" u2="," k="82"/><hkern u1="Ö" u2="„" k="82"/><hkern u1="Ö" u2="‚" k="82"/><hkern u1="Ö" u2="Ÿ" k="20"/><hkern u1="Ö" u2="Ý" k="20"/><hkern u1="Ö" u2="Å" k="41"/><hkern u1="Ö" u2="Ä" k="41"/><hkern u1="Ö" u2="Ã" k="41"/><hkern u1="Ö" u2="Â" k="41"/><hkern u1="Ö" u2="Á" k="41"/><hkern u1="Ö" u2="À" k="41"/><hkern u1="Ö" u2="Z" k="20"/><hkern u1="Ö" u2="Y" k="20"/><hkern u1="Ö" u2="X" k="41"/><hkern u1="Ö" u2="W" k="20"/><hkern u1="Ö" u2="V" k="20"/><hkern u1="Ö" u2="T" k="61"/><hkern u1="Ö" u2="A" k="41"/><hkern u1="Ö" u2="." k="82"/><hkern u1="Ö" u2="," k="82"/><hkern u1="Ø" u2="„" k="82"/><hkern u1="Ø" u2="‚" k="82"/><hkern u1="Ø" u2="Ÿ" k="20"/><hkern u1="Ø" u2="Ý" k="20"/><hkern u1="Ø" u2="Å" k="41"/><hkern u1="Ø" u2="Ä" k="41"/><hkern u1="Ø" u2="Ã" k="41"/><hkern u1="Ø" u2="Â" k="41"/><hkern u1="Ø" u2="Á" k="41"/><hkern u1="Ø" u2="À" k="41"/><hkern u1="Ø" u2="Z" k="20"/><hkern u1="Ø" u2="Y" k="20"/><hkern u1="Ø" u2="X" k="41"/><hkern u1="Ø" u2="W" k="20"/><hkern u1="Ø" u2="V" k="20"/><hkern u1="Ø" u2="T" k="61"/><hkern u1="Ø" u2="A" k="41"/><hkern u1="Ø" u2="." k="82"/><hkern u1="Ø" u2="," k="82"/><hkern u1="Ù" u2="„" k="41"/><hkern u1="Ù" u2="‚" k="41"/><hkern u1="Ù" u2="Å" k="20"/><hkern u1="Ù" u2="Ä" k="20"/><hkern u1="Ù" u2="Ã" k="20"/><hkern u1="Ù" u2="Â" k="20"/><hkern u1="Ù" u2="Á" k="20"/><hkern u1="Ù" u2="À" k="20"/><hkern u1="Ù" u2="A" k="20"/><hkern u1="Ù" u2="." k="41"/><hkern u1="Ù" u2="," k="41"/><hkern u1="Ú" u2="„" k="41"/><hkern u1="Ú" u2="‚" k="41"/><hkern u1="Ú" u2="Å" k="20"/><hkern u1="Ú" u2="Ä" k="20"/><hkern u1="Ú" u2="Ã" k="20"/><hkern u1="Ú" u2="Â" k="20"/><hkern u1="Ú" u2="Á" k="20"/><hkern u1="Ú" u2="À" k="20"/><hkern u1="Ú" u2="A" k="20"/><hkern u1="Ú" u2="." k="41"/><hkern u1="Ú" u2="," k="41"/><hkern u1="Û" u2="„" k="41"/><hkern u1="Û" u2="‚" k="41"/><hkern u1="Û" u2="Å" k="20"/><hkern u1="Û" u2="Ä" k="20"/><hkern u1="Û" u2="Ã" k="20"/><hkern u1="Û" u2="Â" k="20"/><hkern u1="Û" u2="Á" k="20"/><hkern u1="Û" u2="À" k="20"/><hkern u1="Û" u2="A" k="20"/><hkern u1="Û" u2="." k="41"/><hkern u1="Û" u2="," k="41"/><hkern u1="Ü" u2="„" k="41"/><hkern u1="Ü" u2="‚" k="41"/><hkern u1="Ü" u2="Å" k="20"/><hkern u1="Ü" u2="Ä" k="20"/><hkern u1="Ü" u2="Ã" k="20"/><hkern u1="Ü" u2="Â" k="20"/><hkern u1="Ü" u2="Á" k="20"/><hkern u1="Ü" u2="À" k="20"/><hkern u1="Ü" u2="A" k="20"/><hkern u1="Ü" u2="." k="41"/><hkern u1="Ü" u2="," k="41"/><hkern u1="Ý" u2="„" k="123"/><hkern u1="Ý" u2="‚" k="123"/><hkern u1="Ý" u2="œ" k="102"/><hkern u1="Ý" u2="Œ" k="41"/><hkern u1="Ý" u2="ü" k="61"/><hkern u1="Ý" u2="û" k="61"/><hkern u1="Ý" u2="ú" k="61"/><hkern u1="Ý" u2="ù" k="61"/><hkern u1="Ý" u2="ø" k="102"/><hkern u1="Ý" u2="ö" k="102"/><hkern u1="Ý" u2="õ" k="102"/><hkern u1="Ý" u2="ô" k="102"/><hkern u1="Ý" u2="ó" k="102"/><hkern u1="Ý" u2="ò" k="102"/><hkern u1="Ý" u2="ë" k="102"/><hkern u1="Ý" u2="ê" k="102"/><hkern u1="Ý" u2="é" k="102"/><hkern u1="Ý" u2="è" k="102"/><hkern u1="Ý" u2="ç" k="102"/><hkern u1="Ý" u2="æ" k="102"/><hkern u1="Ý" u2="å" k="102"/><hkern u1="Ý" u2="ä" k="102"/><hkern u1="Ý" u2="ã" k="102"/><hkern u1="Ý" u2="â" k="102"/><hkern u1="Ý" u2="á" k="102"/><hkern u1="Ý" u2="à" k="102"/><hkern u1="Ý" u2="Ø" k="41"/><hkern u1="Ý" u2="Ö" k="41"/><hkern u1="Ý" u2="Õ" k="41"/><hkern u1="Ý" u2="Ô" k="41"/><hkern u1="Ý" u2="Ó" k="41"/><hkern u1="Ý" u2="Ò" k="41"/><hkern u1="Ý" u2="Ç" k="41"/><hkern u1="Ý" u2="Å" k="123"/><hkern u1="Ý" u2="Ä" k="123"/><hkern u1="Ý" u2="Ã" k="123"/><hkern u1="Ý" u2="Â" k="123"/><hkern u1="Ý" u2="Á" k="123"/><hkern u1="Ý" u2="À" k="123"/><hkern u1="Ý" u2="z" k="41"/><hkern u1="Ý" u2="u" k="61"/><hkern u1="Ý" u2="s" k="82"/><hkern u1="Ý" u2="r" k="61"/><hkern u1="Ý" u2="q" k="102"/><hkern u1="Ý" u2="p" k="61"/><hkern u1="Ý" u2="o" k="102"/><hkern u1="Ý" u2="n" k="61"/><hkern u1="Ý" u2="m" k="61"/><hkern u1="Ý" u2="g" k="41"/><hkern u1="Ý" u2="e" k="102"/><hkern u1="Ý" u2="d" k="102"/><hkern u1="Ý" u2="c" k="102"/><hkern u1="Ý" u2="a" k="102"/><hkern u1="Ý" u2="Q" k="41"/><hkern u1="Ý" u2="O" k="41"/><hkern u1="Ý" u2="G" k="41"/><hkern u1="Ý" u2="C" k="41"/><hkern u1="Ý" u2="A" k="123"/><hkern u1="Ý" u2="?" k="-41"/><hkern u1="Ý" u2="." k="123"/><hkern u1="Ý" u2="," k="123"/><hkern u1="Þ" u2="„" k="266"/><hkern u1="Þ" u2="‚" k="266"/><hkern u1="Þ" u2="Å" k="102"/><hkern u1="Þ" u2="Ä" k="102"/><hkern u1="Þ" u2="Ã" k="102"/><hkern u1="Þ" u2="Â" k="102"/><hkern u1="Þ" u2="Á" k="102"/><hkern u1="Þ" u2="À" k="102"/><hkern u1="Þ" u2="Z" k="20"/><hkern u1="Þ" u2="X" k="41"/><hkern u1="Þ" u2="A" k="102"/><hkern u1="Þ" u2="." k="266"/><hkern u1="Þ" u2="," k="266"/><hkern u1="à" u2="”" k="20"/><hkern u1="à" u2="’" k="20"/><hkern u1="à" u2="'" k="20"/><hkern u1="à" u2="&quot;" k="20"/><hkern u1="á" u2="”" k="20"/><hkern u1="á" u2="’" k="20"/><hkern u1="á" u2="'" k="20"/><hkern u1="á" u2="&quot;" k="20"/><hkern u1="â" u2="”" k="20"/><hkern u1="â" u2="’" k="20"/><hkern u1="â" u2="'" k="20"/><hkern u1="â" u2="&quot;" k="20"/><hkern u1="ã" u2="”" k="20"/><hkern u1="ã" u2="’" k="20"/><hkern u1="ã" u2="'" k="20"/><hkern u1="ã" u2="&quot;" k="20"/><hkern u1="ä" u2="”" k="20"/><hkern u1="ä" u2="’" k="20"/><hkern u1="ä" u2="'" k="20"/><hkern u1="ä" u2="&quot;" k="20"/><hkern u1="å" u2="”" k="20"/><hkern u1="å" u2="’" k="20"/><hkern u1="å" u2="'" k="20"/><hkern u1="å" u2="&quot;" k="20"/><hkern u1="è" u2="”" k="20"/><hkern u1="è" u2="’" k="20"/><hkern u1="è" u2="ý" k="41"/><hkern u1="è" u2="z" k="20"/><hkern u1="è" u2="y" k="41"/><hkern u1="è" u2="x" k="41"/><hkern u1="è" u2="w" k="41"/><hkern u1="è" u2="v" k="41"/><hkern u1="è" u2="'" k="20"/><hkern u1="è" u2="&quot;" k="20"/><hkern u1="é" u2="”" k="20"/><hkern u1="é" u2="’" k="20"/><hkern u1="é" u2="ý" k="41"/><hkern u1="é" u2="z" k="20"/><hkern u1="é" u2="y" k="41"/><hkern u1="é" u2="x" k="41"/><hkern u1="é" u2="w" k="41"/><hkern u1="é" u2="v" k="41"/><hkern u1="é" u2="'" k="20"/><hkern u1="é" u2="&quot;" k="20"/><hkern u1="ê" u2="”" k="20"/><hkern u1="ê" u2="’" k="20"/><hkern u1="ê" u2="ý" k="41"/><hkern u1="ê" u2="z" k="20"/><hkern u1="ê" u2="y" k="41"/><hkern u1="ê" u2="x" k="41"/><hkern u1="ê" u2="w" k="41"/><hkern u1="ê" u2="v" k="41"/><hkern u1="ê" u2="'" k="20"/><hkern u1="ê" u2="&quot;" k="20"/><hkern u1="ë" u2="”" k="20"/><hkern u1="ë" u2="’" k="20"/><hkern u1="ë" u2="ý" k="41"/><hkern u1="ë" u2="z" k="20"/><hkern u1="ë" u2="y" k="41"/><hkern u1="ë" u2="x" k="41"/><hkern u1="ë" u2="w" k="41"/><hkern u1="ë" u2="v" k="41"/><hkern u1="ë" u2="'" k="20"/><hkern u1="ë" u2="&quot;" k="20"/><hkern u1="ð" u2="”" k="20"/><hkern u1="ð" u2="’" k="20"/><hkern u1="ð" u2="ý" k="41"/><hkern u1="ð" u2="z" k="20"/><hkern u1="ð" u2="y" k="41"/><hkern u1="ð" u2="x" k="41"/><hkern u1="ð" u2="w" k="41"/><hkern u1="ð" u2="v" k="41"/><hkern u1="ð" u2="'" k="20"/><hkern u1="ð" u2="&quot;" k="20"/><hkern u1="ò" u2="”" k="20"/><hkern u1="ò" u2="’" k="20"/><hkern u1="ò" u2="ý" k="41"/><hkern u1="ò" u2="z" k="20"/><hkern u1="ò" u2="y" k="41"/><hkern u1="ò" u2="x" k="41"/><hkern u1="ò" u2="w" k="41"/><hkern u1="ò" u2="v" k="41"/><hkern u1="ò" u2="'" k="20"/><hkern u1="ò" u2="&quot;" k="20"/><hkern u1="ó" u2="”" k="20"/><hkern u1="ó" u2="’" k="20"/><hkern u1="ó" u2="ý" k="41"/><hkern u1="ó" u2="z" k="20"/><hkern u1="ó" u2="y" k="41"/><hkern u1="ó" u2="x" k="41"/><hkern u1="ó" u2="w" k="41"/><hkern u1="ó" u2="v" k="41"/><hkern u1="ó" u2="'" k="20"/><hkern u1="ó" u2="&quot;" k="20"/><hkern u1="ô" u2="”" k="20"/><hkern u1="ô" u2="’" k="20"/><hkern u1="ô" u2="ý" k="41"/><hkern u1="ô" u2="z" k="20"/><hkern u1="ô" u2="y" k="41"/><hkern u1="ô" u2="x" k="41"/><hkern u1="ô" u2="w" k="41"/><hkern u1="ô" u2="v" k="41"/><hkern u1="ô" u2="'" k="20"/><hkern u1="ô" u2="&quot;" k="20"/><hkern u1="ö" u2="”" k="41"/><hkern u1="ö" u2="’" k="41"/><hkern u1="ö" u2="'" k="41"/><hkern u1="ö" u2="&quot;" k="41"/><hkern u1="ø" u2="”" k="20"/><hkern u1="ø" u2="’" k="20"/><hkern u1="ø" u2="ý" k="41"/><hkern u1="ø" u2="z" k="20"/><hkern u1="ø" u2="y" k="41"/><hkern u1="ø" u2="x" k="41"/><hkern u1="ø" u2="w" k="41"/><hkern u1="ø" u2="v" k="41"/><hkern u1="ø" u2="'" k="20"/><hkern u1="ø" u2="&quot;" k="20"/><hkern u1="ý" u2="„" k="82"/><hkern u1="ý" u2="”" k="-82"/><hkern u1="ý" u2="‚" k="82"/><hkern u1="ý" u2="’" k="-82"/><hkern u1="ý" u2="?" k="-41"/><hkern u1="ý" u2="." k="82"/><hkern u1="ý" u2="," k="82"/><hkern u1="ý" u2="'" k="-82"/><hkern u1="ý" u2="&quot;" k="-82"/><hkern u1="þ" u2="”" k="20"/><hkern u1="þ" u2="’" k="20"/><hkern u1="þ" u2="ý" k="41"/><hkern u1="þ" u2="z" k="20"/><hkern u1="þ" u2="y" k="41"/><hkern u1="þ" u2="x" k="41"/><hkern u1="þ" u2="w" k="41"/><hkern u1="þ" u2="v" k="41"/><hkern u1="þ" u2="'" k="20"/><hkern u1="þ" u2="&quot;" k="20"/><hkern u1="ÿ" u2="„" k="82"/><hkern u1="ÿ" u2="”" k="-82"/><hkern u1="ÿ" u2="‚" k="82"/><hkern u1="ÿ" u2="’" k="-82"/><hkern u1="ÿ" u2="?" k="-41"/><hkern u1="ÿ" u2="." k="82"/><hkern u1="ÿ" u2="," k="82"/><hkern u1="ÿ" u2="'" k="-82"/><hkern u1="ÿ" u2="&quot;" k="-82"/><hkern u1="Œ" u2="J" k="-123"/><hkern u1="Ÿ" u2="„" k="123"/><hkern u1="Ÿ" u2="‚" k="123"/><hkern u1="Ÿ" u2="œ" k="102"/><hkern u1="Ÿ" u2="Œ" k="41"/><hkern u1="Ÿ" u2="ü" k="61"/><hkern u1="Ÿ" u2="û" k="61"/><hkern u1="Ÿ" u2="ú" k="61"/><hkern u1="Ÿ" u2="ù" k="61"/><hkern u1="Ÿ" u2="ø" k="102"/><hkern u1="Ÿ" u2="ö" k="102"/><hkern u1="Ÿ" u2="õ" k="102"/><hkern u1="Ÿ" u2="ô" k="102"/><hkern u1="Ÿ" u2="ó" k="102"/><hkern u1="Ÿ" u2="ò" k="102"/><hkern u1="Ÿ" u2="ë" k="102"/><hkern u1="Ÿ" u2="ê" k="102"/><hkern u1="Ÿ" u2="é" k="102"/><hkern u1="Ÿ" u2="è" k="102"/><hkern u1="Ÿ" u2="ç" k="102"/><hkern u1="Ÿ" u2="æ" k="102"/><hkern u1="Ÿ" u2="å" k="102"/><hkern u1="Ÿ" u2="ä" k="102"/><hkern u1="Ÿ" u2="ã" k="102"/><hkern u1="Ÿ" u2="â" k="102"/><hkern u1="Ÿ" u2="á" k="102"/><hkern u1="Ÿ" u2="à" k="102"/><hkern u1="Ÿ" u2="Ø" k="41"/><hkern u1="Ÿ" u2="Ö" k="41"/><hkern u1="Ÿ" u2="Õ" k="41"/><hkern u1="Ÿ" u2="Ô" k="41"/><hkern u1="Ÿ" u2="Ó" k="41"/><hkern u1="Ÿ" u2="Ò" k="41"/><hkern u1="Ÿ" u2="Ç" k="41"/><hkern u1="Ÿ" u2="Å" k="123"/><hkern u1="Ÿ" u2="Ä" k="123"/><hkern u1="Ÿ" u2="Ã" k="123"/><hkern u1="Ÿ" u2="Â" k="123"/><hkern u1="Ÿ" u2="Á" k="123"/><hkern u1="Ÿ" u2="À" k="123"/><hkern u1="Ÿ" u2="z" k="41"/><hkern u1="Ÿ" u2="u" k="61"/><hkern u1="Ÿ" u2="s" k="82"/><hkern u1="Ÿ" u2="r" k="61"/><hkern u1="Ÿ" u2="q" k="102"/><hkern u1="Ÿ" u2="p" k="61"/><hkern u1="Ÿ" u2="o" k="102"/><hkern u1="Ÿ" u2="n" k="61"/><hkern u1="Ÿ" u2="m" k="61"/><hkern u1="Ÿ" u2="g" k="41"/><hkern u1="Ÿ" u2="e" k="102"/><hkern u1="Ÿ" u2="d" k="102"/><hkern u1="Ÿ" u2="c" k="102"/><hkern u1="Ÿ" u2="a" k="102"/><hkern u1="Ÿ" u2="Q" k="41"/><hkern u1="Ÿ" u2="O" k="41"/><hkern u1="Ÿ" u2="G" k="41"/><hkern u1="Ÿ" u2="C" k="41"/><hkern u1="Ÿ" u2="A" k="123"/><hkern u1="Ÿ" u2="?" k="-41"/><hkern u1="Ÿ" u2="." k="123"/><hkern u1="Ÿ" u2="," k="123"/><hkern u1="–" u2="T" k="82"/><hkern u1="—" u2="T" k="82"/><hkern u1="‘" u2="Ÿ" k="-20"/><hkern u1="‘" u2="œ" k="123"/><hkern u1="‘" u2="ü" k="61"/><hkern u1="‘" u2="û" k="61"/><hkern u1="‘" u2="ú" k="61"/><hkern u1="‘" u2="ù" k="61"/><hkern u1="‘" u2="ø" k="123"/><hkern u1="‘" u2="ö" k="123"/><hkern u1="‘" u2="õ" k="123"/><hkern u1="‘" u2="ô" k="123"/><hkern u1="‘" u2="ó" k="123"/><hkern u1="‘" u2="ò" k="123"/><hkern u1="‘" u2="ë" k="123"/><hkern u1="‘" u2="ê" k="123"/><hkern u1="‘" u2="é" k="123"/><hkern u1="‘" u2="è" k="123"/><hkern u1="‘" u2="ç" k="123"/><hkern u1="‘" u2="æ" k="82"/><hkern u1="‘" u2="å" k="82"/><hkern u1="‘" u2="ä" k="82"/><hkern u1="‘" u2="ã" k="82"/><hkern u1="‘" u2="â" k="82"/><hkern u1="‘" u2="á" k="82"/><hkern u1="‘" u2="à" k="123"/><hkern u1="‘" u2="Ý" k="-20"/><hkern u1="‘" u2="Å" k="143"/><hkern u1="‘" u2="Ä" k="143"/><hkern u1="‘" u2="Ã" k="143"/><hkern u1="‘" u2="Â" k="143"/><hkern u1="‘" u2="Á" k="143"/><hkern u1="‘" u2="À" k="143"/><hkern u1="‘" u2="u" k="61"/><hkern u1="‘" u2="s" k="61"/><hkern u1="‘" u2="r" k="61"/><hkern u1="‘" u2="q" k="123"/><hkern u1="‘" u2="p" k="61"/><hkern u1="‘" u2="o" k="123"/><hkern u1="‘" u2="n" k="61"/><hkern u1="‘" u2="m" k="61"/><hkern u1="‘" u2="g" k="61"/><hkern u1="‘" u2="e" k="123"/><hkern u1="‘" u2="d" k="123"/><hkern u1="‘" u2="c" k="123"/><hkern u1="‘" u2="a" k="82"/><hkern u1="‘" u2="Y" k="-20"/><hkern u1="‘" u2="W" k="-41"/><hkern u1="‘" u2="V" k="-41"/><hkern u1="‘" u2="T" k="-41"/><hkern u1="‘" u2="A" k="143"/><hkern u1="’" u2="Ÿ" k="-20"/><hkern u1="’" u2="œ" k="123"/><hkern u1="’" u2="ü" k="61"/><hkern u1="’" u2="û" k="61"/><hkern u1="’" u2="ú" k="61"/><hkern u1="’" u2="ù" k="61"/><hkern u1="’" u2="ø" k="123"/><hkern u1="’" u2="ö" k="123"/><hkern u1="’" u2="õ" k="123"/><hkern u1="’" u2="ô" k="123"/><hkern u1="’" u2="ó" k="123"/><hkern u1="’" u2="ò" k="123"/><hkern u1="’" u2="ë" k="123"/><hkern u1="’" u2="ê" k="123"/><hkern u1="’" u2="é" k="123"/><hkern u1="’" u2="è" k="123"/><hkern u1="’" u2="ç" k="123"/><hkern u1="’" u2="æ" k="82"/><hkern u1="’" u2="å" k="82"/><hkern u1="’" u2="ä" k="82"/><hkern u1="’" u2="ã" k="82"/><hkern u1="’" u2="â" k="82"/><hkern u1="’" u2="á" k="82"/><hkern u1="’" u2="à" k="123"/><hkern u1="’" u2="Ý" k="-20"/><hkern u1="’" u2="Å" k="143"/><hkern u1="’" u2="Ä" k="143"/><hkern u1="’" u2="Ã" k="143"/><hkern u1="’" u2="Â" k="143"/><hkern u1="’" u2="Á" k="143"/><hkern u1="’" u2="À" k="143"/><hkern u1="’" u2="u" k="61"/><hkern u1="’" u2="s" k="61"/><hkern u1="’" u2="r" k="61"/><hkern u1="’" u2="q" k="123"/><hkern u1="’" u2="p" k="61"/><hkern u1="’" u2="o" k="123"/><hkern u1="’" u2="n" k="61"/><hkern u1="’" u2="m" k="61"/><hkern u1="’" u2="g" k="61"/><hkern u1="’" u2="e" k="123"/><hkern u1="’" u2="d" k="123"/><hkern u1="’" u2="c" k="123"/><hkern u1="’" u2="a" k="82"/><hkern u1="’" u2="Y" k="-20"/><hkern u1="’" u2="W" k="-41"/><hkern u1="’" u2="V" k="-41"/><hkern u1="’" u2="T" k="-41"/><hkern u1="’" u2="A" k="143"/><hkern u1="‚" u2="Ÿ" k="123"/><hkern u1="‚" u2="Œ" k="102"/><hkern u1="‚" u2="Ý" k="123"/><hkern u1="‚" u2="Ü" k="41"/><hkern u1="‚" u2="Û" k="41"/><hkern u1="‚" u2="Ú" k="41"/><hkern u1="‚" u2="Ù" k="41"/><hkern u1="‚" u2="Ø" k="102"/><hkern u1="‚" u2="Ö" k="102"/><hkern u1="‚" u2="Õ" k="102"/><hkern u1="‚" u2="Ô" k="102"/><hkern u1="‚" u2="Ó" k="102"/><hkern u1="‚" u2="Ò" k="102"/><hkern u1="‚" u2="Ç" k="102"/><hkern u1="‚" u2="Y" k="123"/><hkern u1="‚" u2="W" k="123"/><hkern u1="‚" u2="V" k="123"/><hkern u1="‚" u2="U" k="41"/><hkern u1="‚" u2="T" k="143"/><hkern u1="‚" u2="Q" k="102"/><hkern u1="‚" u2="O" k="102"/><hkern u1="‚" u2="G" k="102"/><hkern u1="‚" u2="C" k="102"/><hkern u1="“" u2="Ÿ" k="-20"/><hkern u1="“" u2="œ" k="123"/><hkern u1="“" u2="ü" k="61"/><hkern u1="“" u2="û" k="61"/><hkern u1="“" u2="ú" k="61"/><hkern u1="“" u2="ù" k="61"/><hkern u1="“" u2="ø" k="123"/><hkern u1="“" u2="ö" k="123"/><hkern u1="“" u2="õ" k="123"/><hkern u1="“" u2="ô" k="123"/><hkern u1="“" u2="ó" k="123"/><hkern u1="“" u2="ò" k="123"/><hkern u1="“" u2="ë" k="123"/><hkern u1="“" u2="ê" k="123"/><hkern u1="“" u2="é" k="123"/><hkern u1="“" u2="è" k="123"/><hkern u1="“" u2="ç" k="123"/><hkern u1="“" u2="æ" k="82"/><hkern u1="“" u2="å" k="82"/><hkern u1="“" u2="ä" k="82"/><hkern u1="“" u2="ã" k="82"/><hkern u1="“" u2="â" k="82"/><hkern u1="“" u2="á" k="82"/><hkern u1="“" u2="à" k="123"/><hkern u1="“" u2="Ý" k="-20"/><hkern u1="“" u2="Å" k="143"/><hkern u1="“" u2="Ä" k="143"/><hkern u1="“" u2="Ã" k="143"/><hkern u1="“" u2="Â" k="143"/><hkern u1="“" u2="Á" k="143"/><hkern u1="“" u2="À" k="143"/><hkern u1="“" u2="u" k="61"/><hkern u1="“" u2="s" k="61"/><hkern u1="“" u2="r" k="61"/><hkern u1="“" u2="q" k="123"/><hkern u1="“" u2="p" k="61"/><hkern u1="“" u2="o" k="123"/><hkern u1="“" u2="n" k="61"/><hkern u1="“" u2="m" k="61"/><hkern u1="“" u2="g" k="61"/><hkern u1="“" u2="e" k="123"/><hkern u1="“" u2="d" k="123"/><hkern u1="“" u2="c" k="123"/><hkern u1="“" u2="a" k="82"/><hkern u1="“" u2="Y" k="-20"/><hkern u1="“" u2="W" k="-41"/><hkern u1="“" u2="V" k="-41"/><hkern u1="“" u2="T" k="-41"/><hkern u1="“" u2="A" k="143"/><hkern u1="„" u2="Ÿ" k="123"/><hkern u1="„" u2="Œ" k="102"/><hkern u1="„" u2="Ý" k="123"/><hkern u1="„" u2="Ü" k="41"/><hkern u1="„" u2="Û" k="41"/><hkern u1="„" u2="Ú" k="41"/><hkern u1="„" u2="Ù" k="41"/><hkern u1="„" u2="Ø" k="102"/><hkern u1="„" u2="Ö" k="102"/><hkern u1="„" u2="Õ" k="102"/><hkern u1="„" u2="Ô" k="102"/><hkern u1="„" u2="Ó" k="102"/><hkern u1="„" u2="Ò" k="102"/><hkern u1="„" u2="Ç" k="102"/><hkern u1="„" u2="Y" k="123"/><hkern u1="„" u2="W" k="123"/><hkern u1="„" u2="V" k="123"/><hkern u1="„" u2="U" k="41"/><hkern u1="„" u2="T" k="143"/><hkern u1="„" u2="Q" k="102"/><hkern u1="„" u2="O" k="102"/><hkern u1="„" u2="G" k="102"/><hkern u1="„" u2="C" k="102"/></font></defs></svg> \ No newline at end of file diff --git a/lib/web/fonts/opensans/regular/opensans-400.ttf b/lib/web/fonts/opensans/regular/opensans-400.ttf deleted file mode 100644 index c537f8382a429..0000000000000 Binary files a/lib/web/fonts/opensans/regular/opensans-400.ttf and /dev/null differ diff --git a/lib/web/fonts/opensans/semibold/opensans-600.eot b/lib/web/fonts/opensans/semibold/opensans-600.eot deleted file mode 100644 index d8375dd0ab130..0000000000000 Binary files a/lib/web/fonts/opensans/semibold/opensans-600.eot and /dev/null differ diff --git a/lib/web/fonts/opensans/semibold/opensans-600.svg b/lib/web/fonts/opensans/semibold/opensans-600.svg deleted file mode 100644 index d3e4516be5727..0000000000000 --- a/lib/web/fonts/opensans/semibold/opensans-600.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg"><defs><font horiz-adv-x="1169"><font-face units-per-em="2048" ascent="1638" descent="-410"/><glyph unicode="fi" horiz-adv-x="1315" d="M35 0zm688 928H453V0H217v928H35v110l182 72v72q0 196 92 290.5t281 94.5q124 0 244-41l-62-178q-87 28-166 28-80 0-116.5-49.5T453 1178v-72h270V928zM1146 0H911v1106h235V0zM897 1399q0 63 34.5 97t98.5 34q62 0 96.5-34t34.5-97q0-60-34.5-94.5T1030 1270q-64 0-98.5 34.5T897 1399z"/><glyph unicode="fl" horiz-adv-x="1315" d="M35 0zm688 928H453V0H217v928H35v110l182 72v72q0 196 92 290.5t281 94.5q124 0 244-41l-62-178q-87 28-166 28-80 0-116.5-49.5T453 1178v-72h270V928zM1146 0H911v1556h235V0z"/><glyph unicode="ffi" horiz-adv-x="2058" d="M35 0zm688 928H453V0H217v928H35v110l182 72v72q0 196 92 290.5t281 94.5q124 0 244-41l-62-178q-87 28-166 28-80 0-116.5-49.5T453 1178v-72h270V928zm743 0h-270V0H960v928H778v110l182 72v72q0 196 92 290.5t281 94.5q124 0 244-41l-62-178q-87 28-166 28-80 0-116.5-49.5T1196 1178v-72h270V928zM1890 0h-235v1106h235V0zm-249 1399q0 63 34.5 97t98.5 34q62 0 96.5-34t34.5-97q0-60-34.5-94.5T1774 1270q-64 0-98.5 34.5T1641 1399z"/><glyph unicode="ffl" horiz-adv-x="2058" d="M35 0zm688 928H453V0H217v928H35v110l182 72v72q0 196 92 290.5t281 94.5q124 0 244-41l-62-178q-87 28-166 28-80 0-116.5-49.5T453 1178v-72h270V928zm743 0h-270V0H960v928H778v110l182 72v72q0 196 92 290.5t281 94.5q124 0 244-41l-62-178q-87 28-166 28-80 0-116.5-49.5T1196 1178v-72h270V928zM1890 0h-235v1556h235V0z"/><glyph horiz-adv-x="2048"/><glyph horiz-adv-x="2048"/><glyph horiz-adv-x="1044"/><glyph horiz-adv-x="532"/><glyph horiz-adv-x="532"/><glyph horiz-adv-x="532"/><glyph unicode="!" horiz-adv-x="565" d="M371 444H197l-52 1018h277zM133 125q0 74 39 112.5T283 276q71 0 109-40t38-111-38.5-112.5T283-29q-71 0-110.5 40T133 125z"/><glyph unicode="&quot;" horiz-adv-x="893" d="M365 1462l-41-528H174l-41 528h232zm395 0l-41-528H569l-41 528h232z"/><glyph unicode="#" horiz-adv-x="1323" d="M989 870l-55-284h270V418H901L821 0H643l80 418H475L395 0H221l76 418H47v168h283l57 284H123v168h293l80 422h180l-80-422h252l80 422h174l-80-422h252V870H989zM506 586h250l57 284H563z"/><glyph unicode="$" d="M1063 453q0-145-106-239T651 98v-217H518V92q-248 4-407 76v211q86-42 201-70.5T518 279v374l-84 31q-164 63-239.5 150.5T119 1051q0 138 107.5 227T518 1386v168h133v-165q203-7 385-82l-73-183q-157 62-312 74V834l76-29q190-73 263-154t73-198zm-236-15q0 58-40.5 95.5T651 606V287q176 27 176 151zm-473 615q0-57 35.5-95T518 883v311q-80-12-122-49t-42-92z"/><glyph unicode="%" horiz-adv-x="1765" d="M279 1024q0-149 29-222t95-73q132 0 132 295t-132 295q-66 0-95-73t-29-222zm450 2q0-230-82.5-345.5T403 565q-152 0-235.5 119.5T84 1026q0 457 319 457 157 0 241.5-118.5T729 1026zm502-586q0-149 29.5-223t95.5-74q131 0 131 297 0 293-131 293-66 0-95.5-72T1231 440zm450 0q0-230-83-345T1356-20q-152 0-236 118.5T1036 440q0 457 320 457 154 0 239.5-118t85.5-339zm-297 1022L573 0H379l811 1462h194z"/><glyph unicode="&" horiz-adv-x="1516" d="M451 1147q0-63 33.5-119T578 909q113 64 158.5 119.5T782 1153q0 65-43.5 104T623 1296q-79 0-125.5-40.5T451 1147zm149-965q183 0 313 107L530 666q-106-68-146-127.5T344 403q0-98 69.5-159.5T600 182zM96 387q0 131 64 228.5T391 809q-95 111-129.5 187.5T227 1155q0 152 108.5 240t291.5 88q177 0 278-85.5t101-230.5q0-114-67.5-207T713 774l346-334q81 107 135 314h242q-70-284-224-463L1513 0h-303l-149 145Q959 63 843.5 21.5T588-20Q358-20 227 89T96 387z"/><glyph unicode="'" horiz-adv-x="498" d="M365 1462l-41-528H174l-41 528h232z"/><glyph unicode="(" horiz-adv-x="649" d="M82 561q0 265 77.5 496T383 1462h205q-139-188-213-421.5T301 563t74-473 211-414H383Q236-154 159 73T82 561z"/><glyph unicode=")" horiz-adv-x="649" d="M567 561q0-263-77.5-490T266-324H63Q201-137 274.5 91T348 563q0 245-74 477.5T61 1462h205q147-175 224-406.5T567 561z"/><glyph unicode="*" horiz-adv-x="1122" d="M672 1556l-41-382 385 108 28-217-360-29 236-311-199-107-166 338-149-338-205 107 231 311-358 29 35 217 376-108-41 382h228z"/><glyph unicode="+" d="M494 633H96v178h398v408h180V811h399V633H674V227H494v406z"/><glyph unicode="," horiz-adv-x="547" d="M412 215Q364 29 236-264H63Q132 6 166 238h231z"/><glyph unicode="-" horiz-adv-x="659" d="M72 449v200h514V449H72z"/><glyph unicode="." horiz-adv-x="563" d="M133 125q0 73 38 112t110 39q73 0 111-40.5T430 125q0-71-38.5-112.5T281-29 171 12t-38 113z"/><glyph unicode="/" horiz-adv-x="799" d="M782 1462L238 0H16l545 1462h221z"/><glyph unicode="0" d="M1081 731q0-381-122.5-566T584-20q-244 0-370 191T88 731q0 387 122.5 570.5T584 1485q245 0 371-192t126-562zm-755 0q0-299 61.5-427T584 176t197.5 130T844 731q0 294-62.5 425.5T584 1288t-196.5-129T326 731z"/><glyph unicode="1" d="M780 0H545v944q0 169 8 268-23-24-56.5-53T272 975l-118 149 430 338h196V0z"/><glyph unicode="2" d="M1081 0H90v178l377 379q167 171 221.5 242.5T768 934t25 135q0 99-59.5 156T569 1282q-84 0-162.5-31T225 1139L98 1294q122 103 237 146t245 43q204 0 327-106.5t123-286.5q0-99-35.5-188t-109-183.5T641 463L387 217v-10h694V0z"/><glyph unicode="3" d="M1026 1126q0-139-81-231.5T717 770v-8q176-22 264-109.5t88-232.5q0-211-149-325.5T496-20Q253-20 86 59v209q93-46 197-71t200-25q170 0 254 63t84 195q0 117-93 172t-292 55H309v191h129q350 0 350 242 0 94-61 145t-180 51q-83 0-160-23.5T205 1171L90 1335q201 148 467 148 221 0 345-95t124-262z"/><glyph unicode="4" d="M1133 319H936V0H707v319H39v181l668 966h229V514h197V319zM707 514v367q0 196 10 321h-8q-28-66-88-160L258 514h449z"/><glyph unicode="5" d="M586 913q221 0 350-117t129-319q0-234-146.5-365.5T502-20q-245 0-385 79v213q81-46 186-71t195-25q159 0 242 71t83 208q0 262-334 262-47 0-116-9.5T252 686l-105 62 56 714h760v-209H410l-33-362q35 6 85.5 14t123.5 8z"/><glyph unicode="6" d="M94 623q0 858 699 858 110 0 186-17v-196q-76 22-176 22-235 0-353-126T322 760h12q47 81 132 125.5T666 930q199 0 310-122t111-331q0-230-128.5-363.5T608-20q-157 0-273 75.5t-178.5 220T94 623zm510-449q121 0 186.5 78T856 475q0 126-61.5 198T610 745q-76 0-140-32.5t-101-89T332 508q0-141 76.5-237.5T604 174z"/><glyph unicode="7" d="M256 0l578 1253H74v207h1011v-164L510 0H256z"/><glyph unicode="8" d="M584 1481q208 0 329-95.5t121-255.5q0-225-270-358 172-86 244.5-181t72.5-212q0-181-133-290T588-20Q350-20 219 82T88 371q0 122 68.5 219.5T381 764q-134 80-191 169t-57 200q0 159 125 253.5t326 94.5zM313 379q0-104 73-161.5T584 160q129 0 200.5 59.5T856 381q0 81-66 148T590 653l-29 13q-132-58-190-127.5T313 379zm269 921q-100 0-161-49.5T360 1116q0-52 22-93t64-74.5T588 868q120 53 169.5 111.5T807 1116q0 85-61.5 134.5T582 1300z"/><glyph unicode="9" d="M1079 838q0-432-174-645T381-20Q248-20 190-4v197q89-25 179-25 238 0 355 128t128 402h-12q-59-90-142.5-130T502 528q-194 0-305 121T86 981q0 229 128.5 364.5T565 1481q156 0 272-76t179-220.5 63-346.5zm-510 448q-122 0-187-79.5T317 983q0-125 60.5-196.5T561 715q119 0 200 71t81 166q0 89-34.5 166.5T711 1241t-142 45z"/><glyph unicode=":" horiz-adv-x="563" d="M133 125q0 73 38 112t110 39q73 0 111-40.5T430 125q0-71-38.5-112.5T281-29 171 12t-38 113zm0 854q0 151 148 151 75 0 112-40t37-111-38.5-112.5T281 825t-110 41-38 113z"/><glyph unicode=";" horiz-adv-x="569" d="M397 238l15-23Q364 29 236-264H63Q132 6 166 238h231zM131 979q0 151 148 151 75 0 112-40t37-111-38.5-112.5T279 825t-110 41-38 113z"/><glyph unicode="<" d="M1073 221L96 651v121l977 488v-195L340 721l733-303V221z"/><glyph unicode="=" d="M102 831v179h963V831H102zm0-399v178h963V432H102z"/><glyph unicode=">" d="M96 418l733 303-733 344v195l977-488V651L96 221v197z"/><glyph unicode="?" horiz-adv-x="928" d="M283 444v64q0 110 40 183t140 151q119 94 153.5 146t34.5 124q0 84-56 129t-161 45q-95 0-176-27t-158-65l-84 176q203 113 435 113 196 0 311-96t115-265q0-75-22-133.5T788.5 877 635 739q-93-73-124.5-121T479 489v-45H283zm-41-319q0 151 147 151 72 0 110-39.5T537 125q0-71-38.5-112.5T389-29 280 11.5 242 125z"/><glyph unicode="@" horiz-adv-x="1839" d="M1726 739q0-143-45-261.5T1554.5 293 1366 227q-79 0-137 42t-78 114h-12q-49-78-121-117t-162-39q-163 0-256.5 105T506 616q0 206 124 334.5T963 1079q76 0 168.5-13.5T1296 1028l-22-465v-24q0-160 104-160 79 0 125.5 102t46.5 260q0 171-70 300.5T1281 1241t-296 70q-213 0-370.5-88T374 971.5 291 592q0-290 155-446T891-10q221 0 461 90V-84q-210-86-457-86-370 0-577 199.5T111 586q0 261 112 464.5T533.5 1362 983 1470q217 0 386.5-90t263-256.5T1726 739zM698 612q0-233 183-233 193 0 211 293l12 239q-63 17-135 17-128 0-199.5-85T698 612z"/><glyph unicode="A" horiz-adv-x="1354" d="M1100 0L954 406H395L252 0H0l547 1468h260L1354 0h-254zM891 612l-137 398q-15 40-41.5 126T676 1262q-27-123-79-269L465 612h426z"/><glyph unicode="B" horiz-adv-x="1352" d="M193 1462h434q302 0 436.5-88t134.5-278q0-128-66-213T942 776v-10q154-29 226.5-114.5T1241 420q0-197-137.5-308.5T721 0H193v1462zm239-604h230q150 0 219 47.5t69 161.5q0 103-74.5 149T639 1262H432V858zm0-194V201h254q150 0 226.5 57.5T989 440q0 114-78 169t-237 55H432z"/><glyph unicode="C" horiz-adv-x="1298" d="M815 1278q-206 0-324-146T373 729q0-269 113.5-407T815 184q93 0 180 18.5t181 47.5V45q-172-65-390-65-321 0-493 194.5T121 731q0 228 83.5 399T446 1392t371 91q224 0 414-94l-86-199q-74 35-156.5 61.5T815 1278z"/><glyph unicode="D" horiz-adv-x="1503" d="M1382 745q0-362-201-553.5T602 0H193v1462h452q349 0 543-188t194-529zm-252-8q0 525-491 525H432V201h170q528 0 528 536z"/><glyph unicode="E" horiz-adv-x="1143" d="M1020 0H193v1462h827v-202H432V862h551V662H432V203h588V0z"/><glyph unicode="F" horiz-adv-x="1090" d="M430 0H193v1462h825v-202H430V803h551V600H430V0z"/><glyph unicode="G" horiz-adv-x="1487" d="M791 793h538V59q-132-43-253.5-61T813-20q-332 0-512 196.5T121 731q0 353 203 552.5T883 1483q229 0 434-88l-84-199q-178 82-356 82-234 0-370-147T371 729q0-268 122.5-407.5T846 182q116 0 248 29v377H791v205z"/><glyph unicode="H" horiz-adv-x="1538" d="M1346 0h-240v659H432V0H193v1462h239V864h674v598h240V0z"/><glyph unicode="I" horiz-adv-x="625" d="M193 0v1462h239V0H193z"/><glyph unicode="J" horiz-adv-x="612" d="M8-408q-98 0-164 25v201q84-21 146-21 196 0 196 248v1417h240V53q0-224-106.5-342.5T8-408z"/><glyph unicode="K" horiz-adv-x="1309" d="M1309 0h-277L573 662 432 547V0H193v1462h239V764q98 120 195 231l395 467h272q-383-450-549-641z"/><glyph unicode="L" horiz-adv-x="1110" d="M193 0v1462h239V205h619V0H193z"/><glyph unicode="M" horiz-adv-x="1890" d="M825 0L401 1221h-8q17-272 17-510V0H193v1462h337L936 299h6l418 1163h338V0h-230v723q0 109 5.5 284t9.5 212h-8L1036 0H825z"/><glyph unicode="N" horiz-adv-x="1604" d="M1411 0h-293L399 1165h-8l5-65q14-186 14-340V0H193v1462h290l717-1159h6q-2 23-8 167.5t-6 225.5v766h219V0z"/><glyph unicode="O" horiz-adv-x="1612" d="M1491 733q0-357-178.5-555T807-20q-331 0-508.5 196.5T121 735t178.5 556T809 1485q326 0 504-197t178-555zm-1116 0q0-270 109-409.5T807 184q213 0 321.5 138T1237 733q0 269-107.5 408T809 1280q-215 0-324.5-139T375 733z"/><glyph unicode="P" horiz-adv-x="1260" d="M1161 1020q0-229-150-351T584 547H432V0H193v1462h421q274 0 410.5-112t136.5-330zM432 748h127q184 0 270 64t86 200q0 126-77 188t-240 62H432V748z"/><glyph unicode="Q" horiz-adv-x="1612" d="M1491 733q0-266-101.5-448T1094 29l350-377h-322L846-20h-39q-331 0-508.5 196.5T121 735t178.5 556T809 1485q326 0 504-197t178-555zm-1116 0q0-270 109-409.5T807 184q213 0 321.5 138T1237 733q0 269-107.5 408T809 1280q-215 0-324.5-139T375 733z"/><glyph unicode="R" horiz-adv-x="1309" d="M432 782h166q167 0 242 62t75 184q0 124-81 178t-244 54H432V782zm0-198V0H193v1462h413q283 0 419-106t136-320q0-273-284-389L1290 0h-272L668 584H432z"/><glyph unicode="S" horiz-adv-x="1126" d="M1036 397q0-195-141-306T506-20 100 57v226q100-47 212.5-74T522 182q142 0 209.5 54T799 381q0 82-62 139T481 655q-200 81-282 185t-82 250q0 183 130 288t349 105q210 0 418-92l-76-195q-195 82-348 82-116 0-176-50.5T354 1094q0-57 24-97.5t79-76.5 198-95q161-67 236-125t110-131 35-172z"/><glyph unicode="T" horiz-adv-x="1159" d="M698 0H459v1257H29v205h1099v-205H698V0z"/><glyph unicode="U" horiz-adv-x="1520" d="M1339 1462V516q0-162-69.5-283.5t-201-187T754-20q-272 0-423 144T180 520v942h240V537q0-181 84-267t258-86q338 0 338 355v923h239z"/><glyph unicode="V" horiz-adv-x="1274" d="M1026 1462h248L762 0H510L0 1462h246l305-909q24-65 51-167.5T637 233q13 76 40 176t44 148z"/><glyph unicode="W" horiz-adv-x="1937" d="M1542 0h-260l-248 872q-16 57-40 164.5T965 1186q-10-64-32.5-166T895 868L653 0H393L204 732 12 1462h244l209-852q49-205 70-362 11 85 33 190t40 170l238 854h237l244-858q35-119 74-356 15 143 72 364l208 850h242z"/><glyph unicode="X" horiz-adv-x="1274" d="M1270 0H995L629 598 260 0H4l485 758-454 704h266l338-553 338 553h258L778 754z"/><glyph unicode="Y" horiz-adv-x="1212" d="M606 795l346 667h260L725 567V0H485v559L0 1462h260z"/><glyph unicode="Z" horiz-adv-x="1178" d="M1112 0H66v166l737 1091H86v205h1006v-168L352 205h760V0z"/><glyph unicode="[" horiz-adv-x="676" d="M625-324H154v1786h471v-176H369V-147h256v-177z"/><glyph unicode="\" horiz-adv-x="799" d="M238 1462L782 0H561L16 1462h222z"/><glyph unicode="]" horiz-adv-x="676" d="M51-147h256v1433H51v176h469V-324H51v177z"/><glyph unicode="^" horiz-adv-x="1100" d="M29 535l436 935h121l485-935H877l-349 694-307-694H29z"/><glyph unicode="_" horiz-adv-x="879" d="M883-319H-4v135h887v-135z"/><glyph unicode="`" horiz-adv-x="1212" d="M690 1241q-69 52-174.5 150.5T362 1548v21h273q38-70 103.5-161T848 1266v-25H690z"/><glyph unicode="a" horiz-adv-x="1188" d="M860 0l-47 154h-8Q725 53 644 16.5T436-20q-163 0-254.5 88T90 317q0 171 127 258t387 95l191 6v59q0 106-49.5 158.5T592 946q-85 0-163-25t-150-59l-76 168q90 47 197 71.5t202 24.5q211 0 318.5-92T1028 745V0H860zM510 160q128 0 205.5 71.5T793 432v96l-142-6q-166-6-241.5-55.5T334 315q0-74 44-114.5T510 160z"/><glyph unicode="b" horiz-adv-x="1276" d="M733 1126q207 0 322.5-150T1171 555q0-272-117-423.5T729-20q-210 0-326 151h-16L344 0H168v1556h235v-370q0-41-4-122t-6-103h10q112 165 330 165zm-61-192q-142 0-204.5-83.5T403 571v-16q0-202 64-292.5T676 172q125 0 189.5 99T930 557q0 377-258 377z"/><glyph unicode="c" horiz-adv-x="1014" d="M614-20q-251 0-381.5 146.5T102 547q0 279 136.5 429T633 1126q175 0 315-65l-71-189q-149 58-246 58-287 0-287-381 0-186 71.5-279.5T625 176q157 0 297 78V49Q859 12 787.5-4T614-20z"/><glyph unicode="d" horiz-adv-x="1276" d="M541-20q-207 0-323 150T102 551q0 272 117.5 423.5T545 1126q218 0 332-161h12q-17 119-17 188v403h236V0H924l-41 145h-11Q759-20 541-20zm63 190q145 0 211 81.5T883 516v33q0 209-68 297t-213 88q-124 0-191-100.5T344 547q0-184 65-280.5T604 170z"/><glyph unicode="e" horiz-adv-x="1180" d="M651-20q-258 0-403.5 150.5T102 545q0 271 135 426t371 155q219 0 346-133t127-366V500H344q5-161 87-247.5T662 166q98 0 182.5 18.5T1026 246V55Q940 14 852-3T651-20zm-43 968q-112 0-179.5-71T348 670h502q-2 137-66 207.5T608 948z"/><glyph unicode="f" horiz-adv-x="743" d="M723 928H453V0H217v928H35v110l182 72v72q0 196 92 290.5t281 94.5q124 0 244-41l-62-178q-87 28-166 28-80 0-116.5-49.5T453 1178v-72h270V928z"/><glyph unicode="g" horiz-adv-x="1139" d="M1102 1106V977l-189-35q26-35 43-86t17-108q0-171-118-269t-325-98q-53 0-96 8-76-47-76-110 0-38 35.5-57T524 203h193q183 0 278-78t95-225q0-188-155-290T487-492q-226 0-345 80T23-184Q23-82 87.5-12.5T268 84q-47 20-77.5 64.5T160 242q0 62 35 105t104 85q-86 37-139.5 120.5T106 748q0 180 113.5 279t323.5 99q47 0 98.5-6.5T719 1106h383zM233-172q0-76 68.5-117T494-330q192 0 286 55t94 146q0 72-51.5 102.5T631 4H453Q352 4 292.5-43.5T233-172zm101 920q0-104 53.5-160T541 532q204 0 204 218 0 108-50.5 166.5T541 975q-102 0-154.5-58T334 748z"/><glyph unicode="h" horiz-adv-x="1300" d="M1141 0H905v680q0 128-51.5 191T690 934q-148 0-217.5-88.5T403 549V0H168v1556h235v-395q0-95-12-203h15q48 80 133.5 124t199.5 44q402 0 402-405V0z"/><glyph unicode="i" horiz-adv-x="571" d="M403 0H168v1106h235V0zM154 1399q0 63 34.5 97t98.5 34q62 0 96.5-34t34.5-97q0-60-34.5-94.5T287 1270q-64 0-98.5 34.5T154 1399z"/><glyph unicode="j" horiz-adv-x="571" d="M55-492q-106 0-176 25v186q68-18 139-18 150 0 150 170v1235h235V-145q0-171-89.5-259T55-492zm99 1891q0 63 34.5 97t98.5 34q62 0 96.5-34t34.5-97q0-60-34.5-94.5T287 1270q-64 0-98.5 34.5T154 1399z"/><glyph unicode="k" horiz-adv-x="1171" d="M395 584l133 166 334 356h271L688 631 1161 0H885L530 485 401 379V0H168v1556h233V797l-12-213h6z"/><glyph unicode="l" horiz-adv-x="571" d="M403 0H168v1556h235V0z"/><glyph unicode="m" horiz-adv-x="1958" d="M1100 0H864v682q0 127-48 189.5T666 934q-136 0-199.5-88.5T403 551V0H168v1106h184l33-145h12q46 79 133.5 122t192.5 43q255 0 338-174h16q49 82 138 128t204 46q198 0 288.5-100t90.5-305V0h-235v682q0 127-48.5 189.5T1364 934q-137 0-200.5-85.5T1100 586V0z"/><glyph unicode="n" horiz-adv-x="1300" d="M1141 0H905v680q0 128-51.5 191T690 934q-149 0-218-88t-69-295V0H168v1106h184l33-145h12q50 79 142 122t204 43q398 0 398-405V0z"/><glyph unicode="o" horiz-adv-x="1251" d="M1149 555q0-271-139-423T623-20q-155 0-274 70T166 251t-64 304q0 269 138 420t389 151q240 0 380-154.5T1149 555zm-805 0q0-383 283-383 280 0 280 383 0 379-282 379-148 0-214.5-98T344 555z"/><glyph unicode="p" horiz-adv-x="1276" d="M729-20q-210 0-326 151h-14Q403-9 403-39v-453H168v1598h190q8-31 33-148h12q110 168 330 168 207 0 322.5-150T1171 555t-117.5-423T729-20zm-57 954q-140 0-204.5-82T403 590v-35q0-202 64-292.5T676 172q122 0 188 100t66 285q0 186-65.5 281.5T672 934z"/><glyph unicode="q" horiz-adv-x="1276" d="M606 168q148 0 212.5 85.5T883 512v37q0 205-66.5 295T602 934q-126 0-192-100t-66-287q0-379 262-379zM539-20q-205 0-321 150.5T102 551t118 422.5T545 1126q104 0 186.5-38.5T879 961h8l26 145h195V-492H872v469q0 44 4 93t7 75h-13Q766-20 539-20z"/><glyph unicode="r" horiz-adv-x="883" d="M729 1126q71 0 117-10l-23-219q-50 12-104 12-141 0-228.5-92T403 578V0H168v1106h184l31-195h12q55 99 143.5 157t190.5 58z"/><glyph unicode="s" horiz-adv-x="997" d="M911 315q0-162-118-248.5T455-20q-221 0-355 67v203q195-90 363-90 217 0 217 131 0 42-24 70t-79 58-153 68q-191 74-258.5 148T98 827q0 142 114.5 220.5T524 1126q195 0 369-79l-76-177q-179 74-301 74-186 0-186-106 0-52 48.5-88T590 651q137-53 199-97t92-101.5T911 315z"/><glyph unicode="t" horiz-adv-x="805" d="M580 170q86 0 172 27V20Q713 3 651.5-8.5T524-20q-334 0-334 352v596H39v104l162 86 80 234h145v-246h315V928H426V336q0-85 42.5-125.5T580 170z"/><glyph unicode="u" horiz-adv-x="1300" d="M948 0l-33 145h-12Q854 68 763.5 24T557-20Q356-20 257 80t-99 303v723h237V424q0-127 52-190.5T610 170q148 0 217.5 88.5T897 555v551h236V0H948z"/><glyph unicode="v" horiz-adv-x="1096" d="M420 0L0 1106h248l225-643q58-162 70-262h8q9 72 70 262l225 643h250L674 0H420z"/><glyph unicode="w" horiz-adv-x="1673" d="M1075 0L932 516q-26 82-94 381h-9q-58-270-92-383L590 0H330L20 1106h240l141-545q48-202 68-346h6q10 73 30.5 167.5T541 524l168 582h258l163-582q15-49 37.5-150t26.5-157h8q15 123 70 344l143 545h236L1339 0h-264z"/><glyph unicode="x" horiz-adv-x="1128" d="M414 565L43 1106h268l252-387 254 387h266L711 565 1102 0H836L563 414 291 0H25z"/><glyph unicode="y" horiz-adv-x="1098" d="M0 1106h256l225-627q51-134 68-252h8q9 55 33 133.5T844 1106h254L625-147Q496-492 195-492q-78 0-152 17v186q53-12 121-12 170 0 239 197L444 0z"/><glyph unicode="z" horiz-adv-x="979" d="M907 0H68v145l559 781H102v180h789V942L344 180h563V0z"/><glyph unicode="{" horiz-adv-x="791" d="M311 287q0 186-266 186v191q135 0 200.5 45.5T311 848v311q0 156 108.5 229.5T745 1462v-182q-114-5-165.5-46.5T528 1110V813q0-199-229-238v-12q229-36 229-237V27q0-82 51-124t166-44v-183q-231 2-332.5 78.5T311 2v285z"/><glyph unicode="|" horiz-adv-x="1128" d="M473 1552h180V-481H473v2033z"/><glyph unicode="}" horiz-adv-x="760" d="M463-20q0-156-99.5-229T45-324v183q95 1 148 38.5T246 27v262q0 121 53 187t176 87v12q-229 39-229 238v297q0 82-45.5 123.5T45 1280v182q223 0 320.5-76.5T463 1135V848q0-100 63.5-142T715 664V473q-123 0-187.5-42.5T463 287V-20z"/><glyph unicode="~" d="M330 692q-50 0-111.5-30T96 571v191q99 108 250 108 66 0 125-13t147-50q131-55 220-55 52 0 114.5 31t120.5 89V682Q968 571 823 571q-65 0-127.5 15.5T549 637q-127 55-219 55z"/><glyph unicode="¡" horiz-adv-x="565" d="M193 645h174l51-1016H141zm237 320q0-74-37.5-113T281 813q-72 0-110 39.5T133 965q0 69 38 111t110 42 110.5-40.5T430 965z"/><glyph unicode="¢" d="M987 238q-119-59-258-64V-20H573v200q-207 31-307 171T166 741q0 254 100.5 397T573 1313v170h158v-162q152-5 283-66l-70-188q-146 59-250 59-146 0-216-95t-70-288q0-194 72-283t210-89q75 0 142.5 15T987 438V238z"/><glyph unicode="£" d="M690 1481q194 0 375-82l-76-182q-162 71-284 71-205 0-205-219V825h397V653H500V471q0-91-33-155T354 207h756V0H72v195q98 30 145 96t47 178v184H76v172h188v256q0 188 113.5 294T690 1481z"/><glyph unicode="¤" d="M186 723q0 109 64 213l-133 133 121 119 131-129q100 63 215 63t213-65l133 131 121-117-131-133q63-100 63-215 0-119-63-217l129-129-119-119-133 129q-99-61-213-61-126 0-215 61L238 260 119 379l131 129q-64 99-64 215zm168 0q0-98 68-164.5T584 492q97 0 165 66.5T817 723q0 97-68 165t-165 68q-93 0-161.5-68T354 723z"/><glyph unicode="¥" d="M584 797l321 665h244L750 702h227V551H696V397h281V244H696V0H471v244H188v153h283v154H188v151h224L18 1462h246z"/><glyph unicode="¦" horiz-adv-x="1128" d="M473 1552h180V758H473v794zm0-1237h180v-796H473v796z"/><glyph unicode="§" horiz-adv-x="1026" d="M129 807q0 80 38.5 145.5T279 1061q-146 83-146 235 0 129 109.5 202t294.5 73q91 0 174-17t182-59l-68-162q-116 50-176 63t-121 13q-194 0-194-109 0-54 55-93.5t191-90.5q175-68 250-146.5T905 782q0-177-139-266 139-80 139-223 0-142-118-224.5T461-14q-212 0-346 71v179q77-40 173-65.5T465 145q235 0 235 131 0 43-21 70t-71 54-147 65q-141 55-206 101.5t-95.5 105T129 807zm184 20q0-45 24-80t78.5-69T610 588q109 65 109 168 0 75-62 126.5T436 987q-54-16-88.5-61.5T313 827z"/><glyph unicode="¨" horiz-adv-x="1212" d="M293 1399q0 62 33.5 89.5T408 1516q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5T801 1516q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="©" horiz-adv-x="1704" d="M893 1034q-111 0-171-80.5T662 731q0-147 54-226t177-79q55 0 118 15t109 36V319q-115-51-235-51-197 0-305.5 120.5T471 731q0 214 110 337.5T887 1192q138 0 274-70l-65-143q-106 55-203 55zM100 731q0 200 100 375t275 276 377 101q200 0 375-100t276-275 101-377q0-197-97-370T1235 84 852-20Q645-20 470 83.5T197.5 360 100 731zm123 0q0-170 84.5-315.5T538 186t314-84q170 0 316 85.5t229.5 230T1481 731q0 168-84.5 314.5t-231 230.5-313.5 84q-168 0-312.5-83T309 1048t-86-317z"/><glyph unicode="ª" horiz-adv-x="754" d="M547 782l-29 97q-46-55-105-82t-130-27q-113 0-169.5 52.5T57 981q0 104 84 159.5t252 61.5l107 4q0 72-34.5 108T362 1350q-90 0-210-56l-54 115q144 70 285 70 138 0 207-62.5t69-187.5V782H547zm-146 316q-71-2-125.5-34T221 983q0-88 96-88 91 0 137 41t46 123v43z"/><glyph unicode="«" horiz-adv-x="1139" d="M82 561l356 432 168-94-282-350 282-348-168-97L82 535v26zm450 0l357 432 168-94-283-350 283-348-168-97-357 431v26z"/><glyph unicode="¬" d="M1073 256H895v377H96v178h977V256z"/><glyph unicode="­" horiz-adv-x="659" d="M72 449zm0 0v200h514V449H72z"/><glyph unicode="®" horiz-adv-x="1704" d="M748 770h69q74 0 112 35t38 100q0 72-36.5 100.5T815 1034h-67V770zm409 139q0-171-153-233l237-397h-211L838 625h-90V279H559v903h262q174 0 255-68t81-205zM100 731q0 200 100 375t275 276 377 101q200 0 375-100t276-275 101-377q0-197-97-370T1235 84 852-20Q645-20 470 83.5T197.5 360 100 731zm123 0q0-170 84.5-315.5T538 186t314-84q170 0 316 85.5t229.5 230T1481 731q0 168-84.5 314.5t-231 230.5-313.5 84q-168 0-312.5-83T309 1048t-86-317z"/><glyph unicode="¯" horiz-adv-x="1024" d="M1030 1556H-6v164h1036v-164z"/><glyph unicode="°" horiz-adv-x="877" d="M109 1153q0 135 95 232.5t234 97.5q138 0 233-96t95-234q0-139-96-233.5T438 825q-88 0-164.5 43.5T153 988t-44 165zm153 0q0-70 51-122t125-52 125 51.5 51 122.5q0 76-52 127t-124 51-124-52-52-126z"/><glyph unicode="±" d="M494 664H96v178h398v407h180V842h399V664H674V258H494v406zM96 0v178h977V0H96z"/><glyph unicode="²" horiz-adv-x="743" d="M678 586H51v135l230 225q117 112 149.5 165t32.5 112q0 52-32 79t-83 27q-93 0-201-88l-94 121q139 119 309 119 136 0 211.5-66t75.5-180q0-83-46-158.5T420 874L281 745h397V586z"/><glyph unicode="³" horiz-adv-x="743" d="M645 1251q0-75-40.5-122.5T485 1042q94-21 141.5-76T674 834q0-127-93-196t-266-69q-148 0-270 62v157q145-79 270-79 179 0 179 135 0 125-199 125H180v133h105q184 0 184 129 0 52-34.5 80t-90.5 28q-57 0-105.5-20T133 1262l-84 114q61 46 134 75.5t171 29.5q134 0 212.5-61.5T645 1251z"/><glyph unicode="´" horiz-adv-x="1212" d="M362 1241v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T518 1241H362z"/><glyph unicode="µ" horiz-adv-x="1309" d="M403 422q0-252 218-252 146 0 215 88.5T905 555v551h236V0H958l-34 147h-13Q863 64 791.5 22T616-20q-140 0-219 90h-4q3-28 6.5-117t3.5-125v-320H168v1598h235V422z"/><glyph unicode="¶" horiz-adv-x="1341" d="M1143-260h-137v1663H815V-260H678v819q-62-18-146-18-216 0-317.5 125T113 1042q0 260 109 387t341 127h580V-260z"/><glyph unicode="·" horiz-adv-x="563" d="M133 723q0 73 38 112t110 39q73 0 111-40.5T430 723q0-71-38.5-112.5T281 569t-110 41-38 113z"/><glyph unicode="¸" horiz-adv-x="442" d="M426-270q0-222-305-222-66 0-121 15v137q54-14 123-14 54 0 85.5 16.5T240-276q0 85-179 110L145 0h152l-41-88q80-21 125-68.5T426-270z"/><glyph unicode="¹" horiz-adv-x="743" d="M532 586H346v512l3 103 5 91q-17-18-40.5-40T172 1141l-88 112 281 209h167V586z"/><glyph unicode="º" horiz-adv-x="780" d="M719 1124q0-164-87.5-259T387 770q-150 0-238 95.5T61 1124q0 169 88.5 262t241.5 93q152 0 240-94.5t88-260.5zm-496 0q0-111 39-166t127-55 127 55 39 166q0 113-39 167.5T389 1346t-127-54.5-39-167.5z"/><glyph unicode="»" horiz-adv-x="1139" d="M1057 535L698 104l-168 97 283 348-283 350 168 94 359-432v-26zm-451 0L248 104 80 201l282 348L80 899l168 94 358-432v-26z"/><glyph unicode="¼" horiz-adv-x="1700" d="M60 0zm1273 1462L477 0H285l858 1462h190zM508 586H322v512l3 103 5 91q-17-18-40.5-40T148 1141l-88 112 281 209h167V586zm1077-409h-125V1h-192v176H876v127l396 579h188V320h125V177zm-317 143v178q0 97 6 197-52-104-88-158l-148-217h230z"/><glyph unicode="½" horiz-adv-x="1700" d="M46 0zm1252 1462L442 0H250l858 1462h190zM494 586H308v512l3 103 5 91q-17-18-40.5-40T134 1141l-88 112 281 209h167V586zM1608 1H981v135l230 225q117 112 149.5 165t32.5 112q0 52-32 79t-83 27q-93 0-201-88l-94 121q139 119 309 119 136 0 211.5-66t75.5-180q0-83-46-158.5T1350 289l-139-129h397V1z"/><glyph unicode="¾" horiz-adv-x="1700" d="M55 0zm1360 1462L559 0H367l858 1462h190zm225-1285h-125V1h-192v176H931v127l396 579h188V320h125V177zm-317 143v178q0 97 6 197-52-104-88-158l-148-217h230zm-668 931q0-75-40.5-122.5T495 1042q94-21 141.5-76T684 834q0-127-93-196t-266-69q-148 0-270 62v157q145-79 270-79 179 0 179 135 0 125-199 125H190v133h105q184 0 184 129 0 52-34.5 80t-90.5 28q-57 0-105.5-20T143 1262l-84 114q61 46 134 75.5t171 29.5q134 0 212.5-61.5T655 1251z"/><glyph unicode="¿" horiz-adv-x="928" d="M651 645v-63q0-106-41-181T467 246Q343 148 312 99T281-25q0-78 54-125t161-47q90 0 174 27.5T836-104l82-179Q698-393 494-393q-207 0-323 95.5T55-33q0 73 21 130t64 109 157 142q94 76 125 124.5T453 600v45h198zm41 320q0-74-37.5-113T543 813q-72 0-110 39.5T395 965q0 69 38 111t110 42 110.5-40.5T692 965z"/><glyph unicode="À" horiz-adv-x="1354" d="M0 0zm1100 0L954 406H395L252 0H0l547 1468h260L1354 0h-254zM891 612l-137 398q-15 40-41.5 126T676 1262q-27-123-79-269L465 612h426zm-229 967q-69 52-174.5 150.5T334 1886v21h273q38-70 103.5-161T820 1604v-25H662z"/><glyph unicode="Á" horiz-adv-x="1354" d="M0 0zm1100 0L954 406H395L252 0H0l547 1468h260L1354 0h-254zM891 612l-137 398q-15 40-41.5 126T676 1262q-27-123-79-269L465 612h426zm-359 967v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T688 1579H532z"/><glyph unicode="Â" horiz-adv-x="1354" d="M0 0zm1100 0L954 406H395L252 0H0l547 1468h260L1354 0h-254zM891 612l-137 398q-15 40-41.5 126T676 1262q-27-123-79-269L465 612h426zm6 967q-123 73-228 180-103-103-225-180H286v25q191 198 254 303h260q63-110 256-303v-25H897z"/><glyph unicode="Ã" horiz-adv-x="1354" d="M0 0zm1100 0L954 406H395L252 0H0l547 1468h260L1354 0h-254zM891 612l-137 398q-15 40-41.5 126T676 1262q-27-123-79-269L465 612h426zm-70 967q-42 0-82.5 17.5t-79.5 39-76 39-71 17.5q-81 0-109-115H281q12 139 77.5 212t167.5 73q43 0 84-17.5t80-39 75.5-39T836 1749q79 0 106 115h125q-12-134-77-209.5T821 1579z"/><glyph unicode="Ä" horiz-adv-x="1354" d="M0 0zm1100 0L954 406H395L252 0H0l547 1468h260L1354 0h-254zM891 612l-137 398q-15 40-41.5 126T676 1262q-27-123-79-269L465 612h426zM363 1737q0 62 33.5 89.5T478 1854q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5T871 1854q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="Å" horiz-adv-x="1354" d="M0 0zm1100 0L954 406H395L252 0H0l547 1468h260L1354 0h-254zM891 612l-137 398q-15 40-41.5 126T676 1262q-27-123-79-269L465 612h426zm22 965q0-102-65.5-165.5T674 1348t-172 62.5-64 164.5q0 101 63.5 163.5T674 1801q104 0 171.5-62t67.5-162zm-133-2q0 50-30 78.5t-76 28.5q-47 0-77-28.5t-30-78.5q0-106 107-106 46 0 76 27.5t30 78.5z"/><glyph unicode="Æ" horiz-adv-x="1868" d="M1747 0H936v406H432L244 0H-2l678 1462h1071v-202h-571V862h532V662h-532V203h571V0zM522 612h414v641H813z"/><glyph unicode="Ç" horiz-adv-x="1298" d="M121 0zm694 1278q-206 0-324-146T373 729q0-269 113.5-407T815 184q93 0 180 18.5t181 47.5V45q-172-65-390-65-321 0-493 194.5T121 731q0 228 83.5 399T446 1392t371 91q224 0 414-94l-86-199q-74 35-156.5 61.5T815 1278zM952-270q0-222-305-222-66 0-121 15v137q54-14 123-14 54 0 85.5 16.5T766-276q0 85-179 110L671 0h152l-41-88q80-21 125-68.5T952-270z"/><glyph unicode="È" horiz-adv-x="1143" d="M193 0zm827 0H193v1462h827v-202H432V862h551V662H432V203h588V0zM617 1579q-69 52-174.5 150.5T289 1886v21h273q38-70 103.5-161T775 1604v-25H617z"/><glyph unicode="É" horiz-adv-x="1143" d="M193 0zm827 0H193v1462h827v-202H432V862h551V662H432V203h588V0zM440 1579v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T596 1579H440z"/><glyph unicode="Ê" horiz-adv-x="1143" d="M193 0zm827 0H193v1462h827v-202H432V862h551V662H432V203h588V0zM831 1579q-123 73-228 180-103-103-225-180H220v25q191 198 254 303h260q63-110 256-303v-25H831z"/><glyph unicode="Ë" horiz-adv-x="1143" d="M193 0zm827 0H193v1462h827v-202H432V862h551V662H432V203h588V0zM297 1737q0 62 33.5 89.5T412 1854q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5T805 1854q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="Ì" horiz-adv-x="625" d="M0 0zm193 0v1462h239V0H193zm129 1579q-69 52-174.5 150.5T-6 1886v21h273q38-70 103.5-161T480 1604v-25H322z"/><glyph unicode="Í" horiz-adv-x="625" d="M179 0zm14 0v1462h239V0H193zm-14 1579v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T335 1579H179z"/><glyph unicode="Î" horiz-adv-x="625" d="M0 0zm193 0v1462h239V0H193zm343 1579q-123 73-228 180-103-103-225-180H-75v25q191 198 254 303h260q63-110 256-303v-25H536z"/><glyph unicode="Ï" horiz-adv-x="625" d="M1 0zm192 0v1462h239V0H193zM1 1737q0 62 33.5 89.5T116 1854q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29T1 1737zm393 0q0 62 33.5 89.5T509 1854q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="Ð" horiz-adv-x="1497" d="M1374 745q0-360-201-552.5T594 0H193v623H47v200h146v639h446q347 0 541-188.5T1374 745zm-252-8q0 260-124.5 392.5T629 1262H432V823h307V623H432V201h160q530 0 530 536z"/><glyph unicode="Ñ" horiz-adv-x="1604" d="M193 0zm1218 0h-293L399 1165h-8l5-65q14-186 14-340V0H193v1462h290l717-1159h6q-2 23-8 167.5t-6 225.5v766h219V0zM954 1579q-42 0-82.5 17.5t-79.5 39-76 39-71 17.5q-81 0-109-115H414q12 139 77.5 212t167.5 73q43 0 84-17.5t80-39 75.5-39T969 1749q79 0 106 115h125q-12-134-77-209.5T954 1579z"/><glyph unicode="Ò" horiz-adv-x="1612" d="M121 0zm1370 733q0-357-178.5-555T807-20q-331 0-508.5 196.5T121 735t178.5 556T809 1485q326 0 504-197t178-555zm-1116 0q0-270 109-409.5T807 184q213 0 321.5 138T1237 733q0 269-107.5 408T809 1280q-215 0-324.5-139T375 733zm434 846q-69 52-174.5 150.5T481 1886v21h273q38-70 103.5-161T967 1604v-25H809z"/><glyph unicode="Ó" horiz-adv-x="1612" d="M121 0zm1370 733q0-357-178.5-555T807-20q-331 0-508.5 196.5T121 735t178.5 556T809 1485q326 0 504-197t178-555zm-1116 0q0-270 109-409.5T807 184q213 0 321.5 138T1237 733q0 269-107.5 408T809 1280q-215 0-324.5-139T375 733zm282 846v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T813 1579H657z"/><glyph unicode="Ô" horiz-adv-x="1612" d="M121 0zm1370 733q0-357-178.5-555T807-20q-331 0-508.5 196.5T121 735t178.5 556T809 1485q326 0 504-197t178-555zm-1116 0q0-270 109-409.5T807 184q213 0 321.5 138T1237 733q0 269-107.5 408T809 1280q-215 0-324.5-139T375 733zm649 846q-123 73-228 180-103-103-225-180H413v25q191 198 254 303h260q63-110 256-303v-25h-159z"/><glyph unicode="Õ" horiz-adv-x="1612" d="M121 0zm1370 733q0-357-178.5-555T807-20q-331 0-508.5 196.5T121 735t178.5 556T809 1485q326 0 504-197t178-555zm-1116 0q0-270 109-409.5T807 184q213 0 321.5 138T1237 733q0 269-107.5 408T809 1280q-215 0-324.5-139T375 733zm575 846q-42 0-82.5 17.5t-79.5 39-76 39-71 17.5q-81 0-109-115H410q12 139 77.5 212t167.5 73q43 0 84-17.5t80-39 75.5-39T965 1749q79 0 106 115h125q-12-134-77-209.5T950 1579z"/><glyph unicode="Ö" horiz-adv-x="1612" d="M121 0zm1370 733q0-357-178.5-555T807-20q-331 0-508.5 196.5T121 735t178.5 556T809 1485q326 0 504-197t178-555zm-1116 0q0-270 109-409.5T807 184q213 0 321.5 138T1237 733q0 269-107.5 408T809 1280q-215 0-324.5-139T375 733zm121 1004q0 62 33.5 89.5T611 1854q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5t81.5 27.5q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="×" d="M457 723l-326 326 125 127 328-326 329 326 125-123-329-330 325-328-123-125-329 326-324-326-125 125z"/><glyph unicode="Ø" horiz-adv-x="1612" d="M1491 733q0-357-178.5-555T807-20q-213 0-361 81L352-76 211 18l98 144Q121 358 121 735q0 362 178.5 556T809 1485q199 0 354-82l90 129 142-92-99-140q195-199 195-567zm-254 0q0 225-80 361L571 244q97-60 236-60 213 0 321.5 138T1237 733zm-862 0q0-231 78-362l587 850q-92 59-231 59-215 0-324.5-139T375 733z"/><glyph unicode="Ù" horiz-adv-x="1520" d="M180 0zm1159 1462V516q0-162-69.5-283.5t-201-187T754-20q-272 0-423 144T180 520v942h240V537q0-181 84-267t258-86q338 0 338 355v923h239zm-594 117q-69 52-174.5 150.5T417 1886v21h273q38-70 103.5-161T903 1604v-25H745z"/><glyph unicode="Ú" horiz-adv-x="1520" d="M180 0zm1159 1462V516q0-162-69.5-283.5t-201-187T754-20q-272 0-423 144T180 520v942h240V537q0-181 84-267t258-86q338 0 338 355v923h239zm-739 117v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T756 1579H600z"/><glyph unicode="Û" horiz-adv-x="1520" d="M180 0zm1159 1462V516q0-162-69.5-283.5t-201-187T754-20q-272 0-423 144T180 520v942h240V537q0-181 84-267t258-86q338 0 338 355v923h239zm-362 117q-123 73-228 180-103-103-225-180H366v25q191 198 254 303h260q63-110 256-303v-25H977z"/><glyph unicode="Ü" horiz-adv-x="1520" d="M180 0zm1159 1462V516q0-162-69.5-283.5t-201-187T754-20q-272 0-423 144T180 520v942h240V537q0-181 84-267t258-86q338 0 338 355v923h239zm-894 275q0 62 33.5 89.5T560 1854q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5T953 1854q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="Ý" horiz-adv-x="1212" d="M0 0zm606 795l346 667h260L725 567V0H485v559L0 1462h260zm-156 784v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T606 1579H450z"/><glyph unicode="Þ" horiz-adv-x="1268" d="M1169 776q0-227-146-349T600 305H432V0H193v1462h239v-243h197q268 0 404-112t136-331zM432 504h133q187 0 273 63t86 203q0 127-78 188.5T596 1020H432V504z"/><glyph unicode="ß" horiz-adv-x="1364" d="M1149 1253q0-74-38.5-140.5T1006 995q-90-69-117-98t-27-57q0-30 22.5-55.5T964 721l95-64q92-62 135.5-109.5T1260 444t22-127q0-165-107-251T864-20q-190 0-299 65v199q58-37 139-61.5T852 158q192 0 192 151 0 61-34.5 105T854 532q-119 73-171 135t-52 146q0 63 34 115.5T770 1034q75 55 107 97.5t32 93.5q0 72-67 112.5T664 1378q-127 0-194-54t-67-159V0H168v1169q0 193 128.5 295.5T664 1567q225 0 355-84t130-230z"/><glyph unicode="à" horiz-adv-x="1188" d="M90 0zm770 0l-47 154h-8Q725 53 644 16.5T436-20q-163 0-254.5 88T90 317q0 171 127 258t387 95l191 6v59q0 106-49.5 158.5T592 946q-85 0-163-25t-150-59l-76 168q90 47 197 71.5t202 24.5q211 0 318.5-92T1028 745V0H860zM510 160q128 0 205.5 71.5T793 432v96l-142-6q-166-6-241.5-55.5T334 315q0-74 44-114.5T510 160zm77 1081q-69 52-174.5 150.5T259 1548v21h273q38-70 103.5-161T745 1266v-25H587z"/><glyph unicode="á" horiz-adv-x="1188" d="M90 0zm770 0l-47 154h-8Q725 53 644 16.5T436-20q-163 0-254.5 88T90 317q0 171 127 258t387 95l191 6v59q0 106-49.5 158.5T592 946q-85 0-163-25t-150-59l-76 168q90 47 197 71.5t202 24.5q211 0 318.5-92T1028 745V0H860zM510 160q128 0 205.5 71.5T793 432v96l-142-6q-166-6-241.5-55.5T334 315q0-74 44-114.5T510 160zm-72 1081v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T594 1241H438z"/><glyph unicode="â" horiz-adv-x="1188" d="M90 0zm770 0l-47 154h-8Q725 53 644 16.5T436-20q-163 0-254.5 88T90 317q0 171 127 258t387 95l191 6v59q0 106-49.5 158.5T592 946q-85 0-163-25t-150-59l-76 168q90 47 197 71.5t202 24.5q211 0 318.5-92T1028 745V0H860zM510 160q128 0 205.5 71.5T793 432v96l-142-6q-166-6-241.5-55.5T334 315q0-74 44-114.5T510 160zm304 1081q-123 73-228 180-103-103-225-180H203v25q191 198 254 303h260q63-110 256-303v-25H814z"/><glyph unicode="ã" horiz-adv-x="1188" d="M90 0zm770 0l-47 154h-8Q725 53 644 16.5T436-20q-163 0-254.5 88T90 317q0 171 127 258t387 95l191 6v59q0 106-49.5 158.5T592 946q-85 0-163-25t-150-59l-76 168q90 47 197 71.5t202 24.5q211 0 318.5-92T1028 745V0H860zM510 160q128 0 205.5 71.5T793 432v96l-142-6q-166-6-241.5-55.5T334 315q0-74 44-114.5T510 160zm238 1081q-42 0-82.5 17.5t-79.5 39-76 39-71 17.5q-81 0-109-115H208q12 139 77.5 212t167.5 73q43 0 84-17.5t80-39 75.5-39T763 1411q79 0 106 115h125q-12-134-77-209.5T748 1241z"/><glyph unicode="ä" horiz-adv-x="1188" d="M90 0zm770 0l-47 154h-8Q725 53 644 16.5T436-20q-163 0-254.5 88T90 317q0 171 127 258t387 95l191 6v59q0 106-49.5 158.5T592 946q-85 0-163-25t-150-59l-76 168q90 47 197 71.5t202 24.5q211 0 318.5-92T1028 745V0H860zM510 160q128 0 205.5 71.5T793 432v96l-142-6q-166-6-241.5-55.5T334 315q0-74 44-114.5T510 160zM282 1399q0 62 33.5 89.5T397 1516q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5T790 1516q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="å" horiz-adv-x="1188" d="M90 0zm770 0l-47 154h-8Q725 53 644 16.5T436-20q-163 0-254.5 88T90 317q0 171 127 258t387 95l191 6v59q0 106-49.5 158.5T592 946q-85 0-163-25t-150-59l-76 168q90 47 197 71.5t202 24.5q211 0 318.5-92T1028 745V0H860zM510 160q128 0 205.5 71.5T793 432v96l-142-6q-166-6-241.5-55.5T334 315q0-74 44-114.5T510 160zm331 1308q0-102-65.5-165.5T602 1239t-172 62.5-64 164.5q0 101 63.5 163.5T602 1692q104 0 171.5-62t67.5-162zm-133-2q0 50-30 78.5t-76 28.5q-47 0-77-28.5t-30-78.5q0-106 107-106 46 0 76 27.5t30 78.5z"/><glyph unicode="æ" horiz-adv-x="1817" d="M90 317q0 172 121.5 258.5T582 670l188 6v76q0 194-201 194-141 0-307-82l-74 166q88 47 192.5 71.5T584 1126q241 0 340-155 120 155 346 155 206 0 328-134.5T1720 629V502h-712q10-336 301-336 184 0 356 80V55q-86-41-171.5-58T1298-20q-140 0-248.5 54.5T874 199Q780 74 683.5 27T442-20q-165 0-258.5 90T90 317zm244-2q0-155 166-155 124 0 196 72.5T768 432v96l-135-6q-155-6-227-54.5T334 315zm932 633q-112 0-177.5-69.5T1014 670h473q0 130-58.5 204T1266 948z"/><glyph unicode="ç" horiz-adv-x="1014" d="M102 0zm512-20q-251 0-381.5 146.5T102 547q0 279 136.5 429T633 1126q175 0 315-65l-71-189q-149 58-246 58-287 0-287-381 0-186 71.5-279.5T625 176q157 0 297 78V49Q859 12 787.5-4T614-20zm168-250q0-222-305-222-66 0-121 15v137q54-14 123-14 54 0 85.5 16.5T596-276q0 85-179 110L501 0h152l-41-88q80-21 125-68.5T782-270z"/><glyph unicode="è" horiz-adv-x="1180" d="M102 0zm549-20q-258 0-403.5 150.5T102 545q0 271 135 426t371 155q219 0 346-133t127-366V500H344q5-161 87-247.5T662 166q98 0 182.5 18.5T1026 246V55Q940 14 852-3T651-20zm-43 968q-112 0-179.5-71T348 670h502q-2 137-66 207.5T608 948zm1 293q-69 52-174.5 150.5T281 1548v21h273q38-70 103.5-161T767 1266v-25H609z"/><glyph unicode="é" horiz-adv-x="1180" d="M102 0zm549-20q-258 0-403.5 150.5T102 545q0 271 135 426t371 155q219 0 346-133t127-366V500H344q5-161 87-247.5T662 166q98 0 182.5 18.5T1026 246V55Q940 14 852-3T651-20zm-43 968q-112 0-179.5-71T348 670h502q-2 137-66 207.5T608 948zm-150 293v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T614 1241H458z"/><glyph unicode="ê" horiz-adv-x="1180" d="M102 0zm549-20q-258 0-403.5 150.5T102 545q0 271 135 426t371 155q219 0 346-133t127-366V500H344q5-161 87-247.5T662 166q98 0 182.5 18.5T1026 246V55Q940 14 852-3T651-20zm-43 968q-112 0-179.5-71T348 670h502q-2 137-66 207.5T608 948zm230 293q-123 73-228 180-103-103-225-180H227v25q191 198 254 303h260q63-110 256-303v-25H838z"/><glyph unicode="ë" horiz-adv-x="1180" d="M102 0zm549-20q-258 0-403.5 150.5T102 545q0 271 135 426t371 155q219 0 346-133t127-366V500H344q5-161 87-247.5T662 166q98 0 182.5 18.5T1026 246V55Q940 14 852-3T651-20zm-43 968q-112 0-179.5-71T348 670h502q-2 137-66 207.5T608 948zm-301 451q0 62 33.5 89.5T422 1516q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5T815 1516q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="ì" horiz-adv-x="571" d="M0 0zm403 0H168v1106h235V0zM259 1241q-69 52-174.5 150.5T-69 1548v21h273q38-70 103.5-161T417 1266v-25H259z"/><glyph unicode="í" horiz-adv-x="571" d="M156 0zm247 0H168v1106h235V0zM156 1241v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T312 1241H156z"/><glyph unicode="î" horiz-adv-x="571" d="M0 0zm403 0H168v1106h235V0zm108 1241q-123 73-228 180-103-103-225-180h-158v25q191 198 254 303h260q63-110 256-303v-25H511z"/><glyph unicode="ï" horiz-adv-x="571" d="M0 0zm403 0H168v1106h235V0zM-25 1399q0 62 33.5 89.5T90 1516q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5T483 1516q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="ð" horiz-adv-x="1243" d="M1149 567q0-279-137.5-433T623-20q-235 0-378 136T102 481q0 231 131 365.5T584 981q214 0 301-111l8 4q-62 189-227 345l-250-150-88 133 204 119q-86 59-167 102l84 146q140-63 258-144l231 138 88-129-188-113q152-140 231.5-330t79.5-424zm-240-45q0 127-75.5 202T627 799q-151 0-218-82t-67-240q0-153 74-234t211-81q148 0 215 91t67 269z"/><glyph unicode="ñ" horiz-adv-x="1300" d="M168 0zm973 0H905v680q0 128-51.5 191T690 934q-149 0-218-88t-69-295V0H168v1106h184l33-145h12q50 79 142 122t204 43q398 0 398-405V0zM809 1241q-42 0-82.5 17.5t-79.5 39-76 39-71 17.5q-81 0-109-115H269q12 139 77.5 212t167.5 73q43 0 84-17.5t80-39 75.5-39T824 1411q79 0 106 115h125q-12-134-77-209.5T809 1241z"/><glyph unicode="ò" horiz-adv-x="1251" d="M102 0zm1047 555q0-271-139-423T623-20q-155 0-274 70T166 251t-64 304q0 269 138 420t389 151q240 0 380-154.5T1149 555zm-805 0q0-383 283-383 280 0 280 383 0 379-282 379-148 0-214.5-98T344 555zm277 686q-69 52-174.5 150.5T293 1548v21h273q38-70 103.5-161T779 1266v-25H621z"/><glyph unicode="ó" horiz-adv-x="1251" d="M102 0zm1047 555q0-271-139-423T623-20q-155 0-274 70T166 251t-64 304q0 269 138 420t389 151q240 0 380-154.5T1149 555zm-805 0q0-383 283-383 280 0 280 383 0 379-282 379-148 0-214.5-98T344 555zm129 686v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T629 1241H473z"/><glyph unicode="ô" horiz-adv-x="1251" d="M102 0zm1047 555q0-271-139-423T623-20q-155 0-274 70T166 251t-64 304q0 269 138 420t389 151q240 0 380-154.5T1149 555zm-805 0q0-383 283-383 280 0 280 383 0 379-282 379-148 0-214.5-98T344 555zm506 686q-123 73-228 180-103-103-225-180H239v25q191 198 254 303h260q63-110 256-303v-25H850z"/><glyph unicode="õ" horiz-adv-x="1251" d="M102 0zm1047 555q0-271-139-423T623-20q-155 0-274 70T166 251t-64 304q0 269 138 420t389 151q240 0 380-154.5T1149 555zm-805 0q0-383 283-383 280 0 280 383 0 379-282 379-148 0-214.5-98T344 555zm431 686q-42 0-82.5 17.5t-79.5 39-76 39-71 17.5q-81 0-109-115H235q12 139 77.5 212t167.5 73q43 0 84-17.5t80-39 75.5-39T790 1411q79 0 106 115h125q-12-134-77-209.5T775 1241z"/><glyph unicode="ö" horiz-adv-x="1251" d="M102 0zm1047 555q0-271-139-423T623-20q-155 0-274 70T166 251t-64 304q0 269 138 420t389 151q240 0 380-154.5T1149 555zm-805 0q0-383 283-383 280 0 280 383 0 379-282 379-148 0-214.5-98T344 555zm-33 844q0 62 33.5 89.5T426 1516q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5T819 1516q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="÷" d="M96 633v178h977V633H96zm361-260q0 64 31.5 99.5T584 508q61 0 93-36t32-99-34-100-91-37q-60 0-93.5 35.5T457 373zm0 698q0 64 31.5 99.5T584 1206q61 0 93-36t32-99-34-100-91-37q-60 0-93.5 35.5T457 1071z"/><glyph unicode="ø" horiz-adv-x="1251" d="M1149 555q0-271-139-423T623-20q-144 0-250 57L297-72 162 18l82 117Q102 290 102 555q0 269 138 420t389 151q144 0 258-63l69 100 136-92-78-108q135-152 135-408zm-805 0q0-135 37-219l391 559q-60 39-147 39-148 0-214.5-98T344 555zm563 0q0 121-33 203L487 205q54-33 140-33 280 0 280 383z"/><glyph unicode="ù" horiz-adv-x="1300" d="M158 0zm790 0l-33 145h-12Q854 68 763.5 24T557-20Q356-20 257 80t-99 303v723h237V424q0-127 52-190.5T610 170q148 0 217.5 88.5T897 555v551h236V0H948zM617 1241q-69 52-174.5 150.5T289 1548v21h273q38-70 103.5-161T775 1266v-25H617z"/><glyph unicode="ú" horiz-adv-x="1300" d="M158 0zm790 0l-33 145h-12Q854 68 763.5 24T557-20Q356-20 257 80t-99 303v723h237V424q0-127 52-190.5T610 170q148 0 217.5 88.5T897 555v551h236V0H948zM501 1241v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T657 1241H501z"/><glyph unicode="û" horiz-adv-x="1300" d="M158 0zm790 0l-33 145h-12Q854 68 763.5 24T557-20Q356-20 257 80t-99 303v723h237V424q0-127 52-190.5T610 170q148 0 217.5 88.5T897 555v551h236V0H948zm-77 1241q-123 73-228 180-103-103-225-180H260v25q191 198 254 303h260q63-110 256-303v-25H871z"/><glyph unicode="ü" horiz-adv-x="1300" d="M158 0zm790 0l-33 145h-12Q854 68 763.5 24T557-20Q356-20 257 80t-99 303v723h237V424q0-127 52-190.5T610 170q148 0 217.5 88.5T897 555v551h236V0H948zM332 1399q0 62 33.5 89.5T447 1516q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5T840 1516q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="ý" horiz-adv-x="1098" d="M0 0zm0 1106h256l225-627q51-134 68-252h8q9 55 33 133.5T844 1106h254L625-147Q496-492 195-492q-78 0-152 17v186q53-12 121-12 170 0 239 197L444 0zm401 135v25q57 70 117.5 156t95.5 147h273v-21q-52-61-155.5-157.5T557 1241H401z"/><glyph unicode="þ" horiz-adv-x="1276" d="M403 961q61 86 142.5 125.5T733 1126q206 0 322-151t116-420q0-272-116.5-423.5T733-20q-219 0-330 149h-14l8-72 6-92v-457H168v2048h235v-430l-7-138-3-27h10zm271-27q-142 0-206.5-82T403 592v-37q0-202 64-292.5T676 172q254 0 254 385 0 190-61.5 283.5T674 934z"/><glyph unicode="ÿ" horiz-adv-x="1098" d="M0 0zm0 1106h256l225-627q51-134 68-252h8q9 55 33 133.5T844 1106h254L625-147Q496-492 195-492q-78 0-152 17v186q53-12 121-12 170 0 239 197L444 0zm239 293q0 62 33.5 89.5T354 1516q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5T747 1516q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="ı" horiz-adv-x="571" d="M403 0H168v1106h235V0z"/><glyph unicode="Œ" horiz-adv-x="1942" d="M1819 0H999Q897-20 788-20q-320 0-493.5 196.5T121 735q0 360 172 555t491 195q115 0 209-23h826v-202h-576V862h539V662h-539V203h576V0zM793 1280q-208 0-315-139T371 733t106-409 314-140q129 0 213 35v1024q-80 37-211 37z"/><glyph unicode="œ" horiz-adv-x="1966" d="M1438-20q-281 0-420 194Q886-20 618-20q-236 0-376 155T102 555q0 272 137 421.5T621 1126q121 0 223-49t168-145q131 194 379 194 221 0 349-133.5T1868 627V500h-738q11-164 85.5-249t228.5-85q102 0 187 18.5t181 61.5V55q-84-40-171.5-57.5T1438-20zM344 555q0-189 65.5-286T621 172q141 0 206.5 95.5T893 551q0 192-66 287.5T616 934q-143 0-207.5-95T344 555zm1049 393q-110 0-177.5-69.5T1137 670h497q0 134-63 206t-178 72z"/><glyph unicode="Ÿ" horiz-adv-x="1212" d="M0 0zm606 795l346 667h260L725 567V0H485v559L0 1462h260zm-313 942q0 62 33.5 89.5T408 1854q53 0 84.5-31t31.5-86q0-53-32-85t-84-32q-48 0-81.5 29t-33.5 88zm393 0q0 62 33.5 89.5T801 1854q53 0 85-31t32-86q0-54-33-85.5t-84-31.5q-48 0-81.5 29t-33.5 88z"/><glyph unicode="ˆ" horiz-adv-x="1227" d="M838 1241q-123 73-228 180-103-103-225-180H227v25q191 198 254 303h260q63-110 256-303v-25H838z"/><glyph unicode="˚" horiz-adv-x="1182" d="M827 1468q0-102-65.5-165.5T588 1239t-172 62.5-64 164.5q0 101 63.5 163.5T588 1692q104 0 171.5-62t67.5-162zm-133-2q0 50-30 78.5t-76 28.5q-47 0-77-28.5t-30-78.5q0-106 107-106 46 0 76 27.5t30 78.5z"/><glyph unicode="˜" horiz-adv-x="1227" d="M776 1241q-42 0-82.5 17.5t-79.5 39-76 39-71 17.5q-81 0-109-115H236q12 139 77.5 212t167.5 73q43 0 84-17.5t80-39 75.5-39T791 1411q79 0 106 115h125q-12-134-77-209.5T776 1241z"/><glyph horiz-adv-x="953"/><glyph horiz-adv-x="1907"/><glyph horiz-adv-x="953"/><glyph horiz-adv-x="1907"/><glyph horiz-adv-x="635"/><glyph horiz-adv-x="476"/><glyph horiz-adv-x="317"/><glyph horiz-adv-x="317"/><glyph horiz-adv-x="238"/><glyph horiz-adv-x="381"/><glyph horiz-adv-x="105"/><glyph unicode="‐" horiz-adv-x="659" d="M72 449v200h514V449H72z"/><glyph unicode="‑" horiz-adv-x="659" d="M72 449v200h514V449H72z"/><glyph unicode="‒" horiz-adv-x="659" d="M72 449v200h514V449H72z"/><glyph unicode="–" horiz-adv-x="1024" d="M82 455v190h860V455H82z"/><glyph unicode="—" horiz-adv-x="2048" d="M82 455v190h1884V455H82z"/><glyph unicode="‘" horiz-adv-x="395" d="M37 961l-12 22q20 83 71 224t105 255h170q-64-256-101-501H37z"/><glyph unicode="’" horiz-adv-x="395" d="M356 1462l15-22q-53-209-176-479H25q69 289 100 501h231z"/><glyph unicode="‚" horiz-adv-x="549" d="M412 215Q364 29 236-264H63Q132 6 166 238h231z"/><glyph unicode="“" horiz-adv-x="813" d="M440 983q53 203 178 479h170q-69-296-100-501H455zm-415 0q20 83 71 224t105 255h170q-64-256-101-501H37z"/><glyph unicode="”" horiz-adv-x="813" d="M371 1440q-53-209-176-479H25q69 289 100 501h231zm417 0q-53-209-176-479H440q69 271 103 501h231z"/><glyph unicode="„" horiz-adv-x="944" d="M391 215Q336 1 215-264H43Q109-4 145 238h232zm418 0Q761 29 633-264H461Q527-4 563 238h232z"/><glyph unicode="•" horiz-adv-x="770" d="M131 748q0 138 66 210t188 72q121 0 187.5-72.5T639 748q0-135-67-209t-187-74-187 72.5T131 748z"/><glyph unicode="…" horiz-adv-x="1677" d="M133 125q0 73 38 112t110 39q73 0 111-40.5T430 125q0-71-38.5-112.5T281-29 171 12t-38 113zm557 0q0 73 38 112t110 39q73 0 111-40.5T987 125q0-71-38.5-112.5T838-29 728 12t-38 113zm557 0q0 73 38 112t110 39q73 0 111-40.5t38-110.5q0-71-38.5-112.5T1395-29t-110 41-38 113z"/><glyph horiz-adv-x="381"/><glyph unicode="‹" horiz-adv-x="688" d="M82 561l356 432 168-94-282-350 282-348-168-97L82 535v26z"/><glyph unicode="›" horiz-adv-x="688" d="M606 535L248 104 80 201l282 348L80 899l168 94 358-432v-26z"/><glyph unicode="⁄" horiz-adv-x="266" d="M655 1462L-201 0h-192l858 1462h190z"/><glyph horiz-adv-x="476"/><glyph unicode="⁴" horiz-adv-x="743" d="M725 762H600V586H408v176H16v127l396 579h188V905h125V762zM408 905v178q0 97 6 197-52-104-88-158L178 905h230z"/><glyph unicode="€" horiz-adv-x="1188" d="M799 1278q-141 0-230.5-84T449 940h456V786H434l-2-45v-55l2-39h408V494H451q64-312 364-312 143 0 293 62V41Q977-20 803-20q-241 0-391.5 132T215 494H63v153h136l-2 37v37l2 65H63v154h150q38 251 191 394t395 143q200 0 358-88l-84-187q-154 76-274 76z"/><glyph unicode="™" horiz-adv-x="1561" d="M375 741H229v592H27v129h553v-129H375V741zm588 0l-185 543h-6l4-119V741H635v721h217l178-534 187 534h210V741h-147v414l4 129h-6l-193-543H963z"/><glyph unicode="" horiz-adv-x="1105" d="M0 1105h1105V0H0v1105z"/><glyph horiz-adv-x="1276" d="M0 0z"/><hkern u1="&quot;" u2="Ÿ" k="-20"/><hkern u1="&quot;" u2="œ" k="123"/><hkern u1="&quot;" u2="ü" k="61"/><hkern u1="&quot;" u2="û" k="61"/><hkern u1="&quot;" u2="ú" k="61"/><hkern u1="&quot;" u2="ù" k="61"/><hkern u1="&quot;" u2="ø" k="123"/><hkern u1="&quot;" u2="ö" k="123"/><hkern u1="&quot;" u2="õ" k="123"/><hkern u1="&quot;" u2="ô" k="123"/><hkern u1="&quot;" u2="ó" k="123"/><hkern u1="&quot;" u2="ò" k="123"/><hkern u1="&quot;" u2="ë" k="123"/><hkern u1="&quot;" u2="ê" k="123"/><hkern u1="&quot;" u2="é" k="123"/><hkern u1="&quot;" u2="è" k="123"/><hkern u1="&quot;" u2="ç" k="123"/><hkern u1="&quot;" u2="æ" k="82"/><hkern u1="&quot;" u2="å" k="82"/><hkern u1="&quot;" u2="ä" k="82"/><hkern u1="&quot;" u2="ã" k="82"/><hkern u1="&quot;" u2="â" k="82"/><hkern u1="&quot;" u2="á" k="82"/><hkern u1="&quot;" u2="à" k="123"/><hkern u1="&quot;" u2="Ý" k="-20"/><hkern u1="&quot;" u2="Å" k="143"/><hkern u1="&quot;" u2="Ä" k="143"/><hkern u1="&quot;" u2="Ã" k="143"/><hkern u1="&quot;" u2="Â" k="143"/><hkern u1="&quot;" u2="Á" k="143"/><hkern u1="&quot;" u2="À" k="143"/><hkern u1="&quot;" u2="u" k="61"/><hkern u1="&quot;" u2="s" k="61"/><hkern u1="&quot;" u2="r" k="61"/><hkern u1="&quot;" u2="q" k="123"/><hkern u1="&quot;" u2="p" k="61"/><hkern u1="&quot;" u2="o" k="123"/><hkern u1="&quot;" u2="n" k="61"/><hkern u1="&quot;" u2="m" k="61"/><hkern u1="&quot;" u2="g" k="61"/><hkern u1="&quot;" u2="e" k="123"/><hkern u1="&quot;" u2="d" k="123"/><hkern u1="&quot;" u2="c" k="123"/><hkern u1="&quot;" u2="a" k="82"/><hkern u1="&quot;" u2="Y" k="-20"/><hkern u1="&quot;" u2="W" k="-41"/><hkern u1="&quot;" u2="V" k="-41"/><hkern u1="&quot;" u2="T" k="-41"/><hkern u1="&quot;" u2="A" k="143"/><hkern u1="'" u2="Ÿ" k="-20"/><hkern u1="'" u2="œ" k="123"/><hkern u1="'" u2="ü" k="61"/><hkern u1="'" u2="û" k="61"/><hkern u1="'" u2="ú" k="61"/><hkern u1="'" u2="ù" k="61"/><hkern u1="'" u2="ø" k="123"/><hkern u1="'" u2="ö" k="123"/><hkern u1="'" u2="õ" k="123"/><hkern u1="'" u2="ô" k="123"/><hkern u1="'" u2="ó" k="123"/><hkern u1="'" u2="ò" k="123"/><hkern u1="'" u2="ë" k="123"/><hkern u1="'" u2="ê" k="123"/><hkern u1="'" u2="é" k="123"/><hkern u1="'" u2="è" k="123"/><hkern u1="'" u2="ç" k="123"/><hkern u1="'" u2="æ" k="82"/><hkern u1="'" u2="å" k="82"/><hkern u1="'" u2="ä" k="82"/><hkern u1="'" u2="ã" k="82"/><hkern u1="'" u2="â" k="82"/><hkern u1="'" u2="á" k="82"/><hkern u1="'" u2="à" k="123"/><hkern u1="'" u2="Ý" k="-20"/><hkern u1="'" u2="Å" k="143"/><hkern u1="'" u2="Ä" k="143"/><hkern u1="'" u2="Ã" k="143"/><hkern u1="'" u2="Â" k="143"/><hkern u1="'" u2="Á" k="143"/><hkern u1="'" u2="À" k="143"/><hkern u1="'" u2="u" k="61"/><hkern u1="'" u2="s" k="61"/><hkern u1="'" u2="r" k="61"/><hkern u1="'" u2="q" k="123"/><hkern u1="'" u2="p" k="61"/><hkern u1="'" u2="o" k="123"/><hkern u1="'" u2="n" k="61"/><hkern u1="'" u2="m" k="61"/><hkern u1="'" u2="g" k="61"/><hkern u1="'" u2="e" k="123"/><hkern u1="'" u2="d" k="123"/><hkern u1="'" u2="c" k="123"/><hkern u1="'" u2="a" k="82"/><hkern u1="'" u2="Y" k="-20"/><hkern u1="'" u2="W" k="-41"/><hkern u1="'" u2="V" k="-41"/><hkern u1="'" u2="T" k="-41"/><hkern u1="'" u2="A" k="143"/><hkern u1="(" u2="J" k="-184"/><hkern u1="," u2="Ÿ" k="123"/><hkern u1="," u2="Œ" k="102"/><hkern u1="," u2="Ý" k="123"/><hkern u1="," u2="Ü" k="41"/><hkern u1="," u2="Û" k="41"/><hkern u1="," u2="Ú" k="41"/><hkern u1="," u2="Ù" k="41"/><hkern u1="," u2="Ø" k="102"/><hkern u1="," u2="Ö" k="102"/><hkern u1="," u2="Õ" k="102"/><hkern u1="," u2="Ô" k="102"/><hkern u1="," u2="Ó" k="102"/><hkern u1="," u2="Ò" k="102"/><hkern u1="," u2="Ç" k="102"/><hkern u1="," u2="Y" k="123"/><hkern u1="," u2="W" k="123"/><hkern u1="," u2="V" k="123"/><hkern u1="," u2="U" k="41"/><hkern u1="," u2="T" k="143"/><hkern u1="," u2="Q" k="102"/><hkern u1="," u2="O" k="102"/><hkern u1="," u2="G" k="102"/><hkern u1="," u2="C" k="102"/><hkern u1="-" u2="T" k="82"/><hkern u1="." u2="Ÿ" k="123"/><hkern u1="." u2="Œ" k="102"/><hkern u1="." u2="Ý" k="123"/><hkern u1="." u2="Ü" k="41"/><hkern u1="." u2="Û" k="41"/><hkern u1="." u2="Ú" k="41"/><hkern u1="." u2="Ù" k="41"/><hkern u1="." u2="Ø" k="102"/><hkern u1="." u2="Ö" k="102"/><hkern u1="." u2="Õ" k="102"/><hkern u1="." u2="Ô" k="102"/><hkern u1="." u2="Ó" k="102"/><hkern u1="." u2="Ò" k="102"/><hkern u1="." u2="Ç" k="102"/><hkern u1="." u2="Y" k="123"/><hkern u1="." u2="W" k="123"/><hkern u1="." u2="V" k="123"/><hkern u1="." u2="U" k="41"/><hkern u1="." u2="T" k="143"/><hkern u1="." u2="Q" k="102"/><hkern u1="." u2="O" k="102"/><hkern u1="." u2="G" k="102"/><hkern u1="." u2="C" k="102"/><hkern u1="A" u2="”" k="143"/><hkern u1="A" u2="’" k="143"/><hkern u1="A" u2="Ÿ" k="123"/><hkern u1="A" u2="Œ" k="41"/><hkern u1="A" u2="Ý" k="123"/><hkern u1="A" u2="Ø" k="41"/><hkern u1="A" u2="Ö" k="41"/><hkern u1="A" u2="Õ" k="41"/><hkern u1="A" u2="Ô" k="41"/><hkern u1="A" u2="Ó" k="41"/><hkern u1="A" u2="Ò" k="41"/><hkern u1="A" u2="Ç" k="41"/><hkern u1="A" u2="Y" k="123"/><hkern u1="A" u2="W" k="82"/><hkern u1="A" u2="V" k="82"/><hkern u1="A" u2="T" k="143"/><hkern u1="A" u2="Q" k="41"/><hkern u1="A" u2="O" k="41"/><hkern u1="A" u2="J" k="-266"/><hkern u1="A" u2="G" k="41"/><hkern u1="A" u2="C" k="41"/><hkern u1="A" u2="'" k="143"/><hkern u1="A" u2="&quot;" k="143"/><hkern u1="B" u2="„" k="82"/><hkern u1="B" u2="‚" k="82"/><hkern u1="B" u2="Ÿ" k="20"/><hkern u1="B" u2="Ý" k="20"/><hkern u1="B" u2="Å" k="41"/><hkern u1="B" u2="Ä" k="41"/><hkern u1="B" u2="Ã" k="41"/><hkern u1="B" u2="Â" k="41"/><hkern u1="B" u2="Á" k="41"/><hkern u1="B" u2="À" k="41"/><hkern u1="B" u2="Z" k="20"/><hkern u1="B" u2="Y" k="20"/><hkern u1="B" u2="X" k="41"/><hkern u1="B" u2="W" k="20"/><hkern u1="B" u2="V" k="20"/><hkern u1="B" u2="T" k="61"/><hkern u1="B" u2="A" k="41"/><hkern u1="B" u2="." k="82"/><hkern u1="B" u2="," k="82"/><hkern u1="C" u2="Œ" k="41"/><hkern u1="C" u2="Ø" k="41"/><hkern u1="C" u2="Ö" k="41"/><hkern u1="C" u2="Õ" k="41"/><hkern u1="C" u2="Ô" k="41"/><hkern u1="C" u2="Ó" k="41"/><hkern u1="C" u2="Ò" k="41"/><hkern u1="C" u2="Ç" k="41"/><hkern u1="C" u2="Q" k="41"/><hkern u1="C" u2="O" k="41"/><hkern u1="C" u2="G" k="41"/><hkern u1="C" u2="C" k="41"/><hkern u1="D" u2="„" k="82"/><hkern u1="D" u2="‚" k="82"/><hkern u1="D" u2="Ÿ" k="20"/><hkern u1="D" u2="Ý" k="20"/><hkern u1="D" u2="Å" k="41"/><hkern u1="D" u2="Ä" k="41"/><hkern u1="D" u2="Ã" k="41"/><hkern u1="D" u2="Â" k="41"/><hkern u1="D" u2="Á" k="41"/><hkern u1="D" u2="À" k="41"/><hkern u1="D" u2="Z" k="20"/><hkern u1="D" u2="Y" k="20"/><hkern u1="D" u2="X" k="41"/><hkern u1="D" u2="W" k="20"/><hkern u1="D" u2="V" k="20"/><hkern u1="D" u2="T" k="61"/><hkern u1="D" u2="A" k="41"/><hkern u1="D" u2="." k="82"/><hkern u1="D" u2="," k="82"/><hkern u1="E" u2="J" k="-123"/><hkern u1="F" u2="„" k="123"/><hkern u1="F" u2="‚" k="123"/><hkern u1="F" u2="Å" k="41"/><hkern u1="F" u2="Ä" k="41"/><hkern u1="F" u2="Ã" k="41"/><hkern u1="F" u2="Â" k="41"/><hkern u1="F" u2="Á" k="41"/><hkern u1="F" u2="À" k="41"/><hkern u1="F" u2="A" k="41"/><hkern u1="F" u2="?" k="-41"/><hkern u1="F" u2="." k="123"/><hkern u1="F" u2="," k="123"/><hkern u1="K" u2="Œ" k="41"/><hkern u1="K" u2="Ø" k="41"/><hkern u1="K" u2="Ö" k="41"/><hkern u1="K" u2="Õ" k="41"/><hkern u1="K" u2="Ô" k="41"/><hkern u1="K" u2="Ó" k="41"/><hkern u1="K" u2="Ò" k="41"/><hkern u1="K" u2="Ç" k="41"/><hkern u1="K" u2="Q" k="41"/><hkern u1="K" u2="O" k="41"/><hkern u1="K" u2="G" k="41"/><hkern u1="K" u2="C" k="41"/><hkern u1="L" u2="”" k="164"/><hkern u1="L" u2="’" k="164"/><hkern u1="L" u2="Ÿ" k="61"/><hkern u1="L" u2="Œ" k="41"/><hkern u1="L" u2="Ý" k="61"/><hkern u1="L" u2="Ü" k="20"/><hkern u1="L" u2="Û" k="20"/><hkern u1="L" u2="Ú" k="20"/><hkern u1="L" u2="Ù" k="20"/><hkern u1="L" u2="Ø" k="41"/><hkern u1="L" u2="Ö" k="41"/><hkern u1="L" u2="Õ" k="41"/><hkern u1="L" u2="Ô" k="41"/><hkern u1="L" u2="Ó" k="41"/><hkern u1="L" u2="Ò" k="41"/><hkern u1="L" u2="Ç" k="41"/><hkern u1="L" u2="Y" k="61"/><hkern u1="L" u2="W" k="41"/><hkern u1="L" u2="V" k="41"/><hkern u1="L" u2="U" k="20"/><hkern u1="L" u2="T" k="41"/><hkern u1="L" u2="Q" k="41"/><hkern u1="L" u2="O" k="41"/><hkern u1="L" u2="G" k="41"/><hkern u1="L" u2="C" k="41"/><hkern u1="L" u2="'" k="164"/><hkern u1="L" u2="&quot;" k="164"/><hkern u1="O" u2="„" k="82"/><hkern u1="O" u2="‚" k="82"/><hkern u1="O" u2="Ÿ" k="20"/><hkern u1="O" u2="Ý" k="20"/><hkern u1="O" u2="Å" k="41"/><hkern u1="O" u2="Ä" k="41"/><hkern u1="O" u2="Ã" k="41"/><hkern u1="O" u2="Â" k="41"/><hkern u1="O" u2="Á" k="41"/><hkern u1="O" u2="À" k="41"/><hkern u1="O" u2="Z" k="20"/><hkern u1="O" u2="Y" k="20"/><hkern u1="O" u2="X" k="41"/><hkern u1="O" u2="W" k="20"/><hkern u1="O" u2="V" k="20"/><hkern u1="O" u2="T" k="61"/><hkern u1="O" u2="A" k="41"/><hkern u1="O" u2="." k="82"/><hkern u1="O" u2="," k="82"/><hkern u1="P" u2="„" k="266"/><hkern u1="P" u2="‚" k="266"/><hkern u1="P" u2="Å" k="102"/><hkern u1="P" u2="Ä" k="102"/><hkern u1="P" u2="Ã" k="102"/><hkern u1="P" u2="Â" k="102"/><hkern u1="P" u2="Á" k="102"/><hkern u1="P" u2="À" k="102"/><hkern u1="P" u2="Z" k="20"/><hkern u1="P" u2="X" k="41"/><hkern u1="P" u2="A" k="102"/><hkern u1="P" u2="." k="266"/><hkern u1="P" u2="," k="266"/><hkern u1="Q" u2="„" k="82"/><hkern u1="Q" u2="‚" k="82"/><hkern u1="Q" u2="Ÿ" k="20"/><hkern u1="Q" u2="Ý" k="20"/><hkern u1="Q" u2="Å" k="41"/><hkern u1="Q" u2="Ä" k="41"/><hkern u1="Q" u2="Ã" k="41"/><hkern u1="Q" u2="Â" k="41"/><hkern u1="Q" u2="Á" k="41"/><hkern u1="Q" u2="À" k="41"/><hkern u1="Q" u2="Z" k="20"/><hkern u1="Q" u2="Y" k="20"/><hkern u1="Q" u2="X" k="41"/><hkern u1="Q" u2="W" k="20"/><hkern u1="Q" u2="V" k="20"/><hkern u1="Q" u2="T" k="61"/><hkern u1="Q" u2="A" k="41"/><hkern u1="Q" u2="." k="82"/><hkern u1="Q" u2="," k="82"/><hkern u1="T" u2="„" k="123"/><hkern u1="T" u2="‚" k="123"/><hkern u1="T" u2="—" k="82"/><hkern u1="T" u2="–" k="82"/><hkern u1="T" u2="œ" k="143"/><hkern u1="T" u2="Œ" k="41"/><hkern u1="T" u2="ý" k="41"/><hkern u1="T" u2="ü" k="102"/><hkern u1="T" u2="û" k="102"/><hkern u1="T" u2="ú" k="102"/><hkern u1="T" u2="ù" k="102"/><hkern u1="T" u2="ø" k="143"/><hkern u1="T" u2="ö" k="143"/><hkern u1="T" u2="õ" k="143"/><hkern u1="T" u2="ô" k="143"/><hkern u1="T" u2="ó" k="143"/><hkern u1="T" u2="ò" k="143"/><hkern u1="T" u2="ë" k="143"/><hkern u1="T" u2="ê" k="143"/><hkern u1="T" u2="é" k="143"/><hkern u1="T" u2="è" k="143"/><hkern u1="T" u2="ç" k="143"/><hkern u1="T" u2="æ" k="164"/><hkern u1="T" u2="å" k="164"/><hkern u1="T" u2="ä" k="164"/><hkern u1="T" u2="ã" k="164"/><hkern u1="T" u2="â" k="164"/><hkern u1="T" u2="á" k="164"/><hkern u1="T" u2="à" k="143"/><hkern u1="T" u2="Ø" k="41"/><hkern u1="T" u2="Ö" k="41"/><hkern u1="T" u2="Õ" k="41"/><hkern u1="T" u2="Ô" k="41"/><hkern u1="T" u2="Ó" k="41"/><hkern u1="T" u2="Ò" k="41"/><hkern u1="T" u2="Ç" k="41"/><hkern u1="T" u2="Å" k="143"/><hkern u1="T" u2="Ä" k="143"/><hkern u1="T" u2="Ã" k="143"/><hkern u1="T" u2="Â" k="143"/><hkern u1="T" u2="Á" k="143"/><hkern u1="T" u2="À" k="143"/><hkern u1="T" u2="z" k="82"/><hkern u1="T" u2="y" k="41"/><hkern u1="T" u2="x" k="41"/><hkern u1="T" u2="w" k="41"/><hkern u1="T" u2="v" k="41"/><hkern u1="T" u2="u" k="102"/><hkern u1="T" u2="s" k="123"/><hkern u1="T" u2="r" k="102"/><hkern u1="T" u2="q" k="143"/><hkern u1="T" u2="p" k="102"/><hkern u1="T" u2="o" k="143"/><hkern u1="T" u2="n" k="102"/><hkern u1="T" u2="m" k="102"/><hkern u1="T" u2="g" k="143"/><hkern u1="T" u2="e" k="143"/><hkern u1="T" u2="d" k="143"/><hkern u1="T" u2="c" k="143"/><hkern u1="T" u2="a" k="164"/><hkern u1="T" u2="T" k="-41"/><hkern u1="T" u2="Q" k="41"/><hkern u1="T" u2="O" k="41"/><hkern u1="T" u2="G" k="41"/><hkern u1="T" u2="C" k="41"/><hkern u1="T" u2="A" k="143"/><hkern u1="T" u2="?" k="-41"/><hkern u1="T" u2="." k="123"/><hkern u1="T" u2="-" k="82"/><hkern u1="T" u2="," k="123"/><hkern u1="U" u2="„" k="41"/><hkern u1="U" u2="‚" k="41"/><hkern u1="U" u2="Å" k="20"/><hkern u1="U" u2="Ä" k="20"/><hkern u1="U" u2="Ã" k="20"/><hkern u1="U" u2="Â" k="20"/><hkern u1="U" u2="Á" k="20"/><hkern u1="U" u2="À" k="20"/><hkern u1="U" u2="A" k="20"/><hkern u1="U" u2="." k="41"/><hkern u1="U" u2="," k="41"/><hkern u1="V" u2="„" k="102"/><hkern u1="V" u2="‚" k="102"/><hkern u1="V" u2="œ" k="41"/><hkern u1="V" u2="Œ" k="20"/><hkern u1="V" u2="ü" k="20"/><hkern u1="V" u2="û" k="20"/><hkern u1="V" u2="ú" k="20"/><hkern u1="V" u2="ù" k="20"/><hkern u1="V" u2="ø" k="41"/><hkern u1="V" u2="ö" k="41"/><hkern u1="V" u2="õ" k="41"/><hkern u1="V" u2="ô" k="41"/><hkern u1="V" u2="ó" k="41"/><hkern u1="V" u2="ò" k="41"/><hkern u1="V" u2="ë" k="41"/><hkern u1="V" u2="ê" k="41"/><hkern u1="V" u2="é" k="41"/><hkern u1="V" u2="è" k="41"/><hkern u1="V" u2="ç" k="41"/><hkern u1="V" u2="æ" k="41"/><hkern u1="V" u2="å" k="41"/><hkern u1="V" u2="ä" k="41"/><hkern u1="V" u2="ã" k="41"/><hkern u1="V" u2="â" k="41"/><hkern u1="V" u2="á" k="41"/><hkern u1="V" u2="à" k="41"/><hkern u1="V" u2="Ø" k="20"/><hkern u1="V" u2="Ö" k="20"/><hkern u1="V" u2="Õ" k="20"/><hkern u1="V" u2="Ô" k="20"/><hkern u1="V" u2="Ó" k="20"/><hkern u1="V" u2="Ò" k="20"/><hkern u1="V" u2="Ç" k="20"/><hkern u1="V" u2="Å" k="82"/><hkern u1="V" u2="Ä" k="82"/><hkern u1="V" u2="Ã" k="82"/><hkern u1="V" u2="Â" k="82"/><hkern u1="V" u2="Á" k="82"/><hkern u1="V" u2="À" k="82"/><hkern u1="V" u2="u" k="20"/><hkern u1="V" u2="s" k="20"/><hkern u1="V" u2="r" k="20"/><hkern u1="V" u2="q" k="41"/><hkern u1="V" u2="p" k="20"/><hkern u1="V" u2="o" k="41"/><hkern u1="V" u2="n" k="20"/><hkern u1="V" u2="m" k="20"/><hkern u1="V" u2="g" k="20"/><hkern u1="V" u2="e" k="41"/><hkern u1="V" u2="d" k="41"/><hkern u1="V" u2="c" k="41"/><hkern u1="V" u2="a" k="41"/><hkern u1="V" u2="Q" k="20"/><hkern u1="V" u2="O" k="20"/><hkern u1="V" u2="G" k="20"/><hkern u1="V" u2="C" k="20"/><hkern u1="V" u2="A" k="82"/><hkern u1="V" u2="?" k="-41"/><hkern u1="V" u2="." k="102"/><hkern u1="V" u2="," k="102"/><hkern u1="W" u2="„" k="102"/><hkern u1="W" u2="‚" k="102"/><hkern u1="W" u2="œ" k="41"/><hkern u1="W" u2="Œ" k="20"/><hkern u1="W" u2="ü" k="20"/><hkern u1="W" u2="û" k="20"/><hkern u1="W" u2="ú" k="20"/><hkern u1="W" u2="ù" k="20"/><hkern u1="W" u2="ø" k="41"/><hkern u1="W" u2="ö" k="41"/><hkern u1="W" u2="õ" k="41"/><hkern u1="W" u2="ô" k="41"/><hkern u1="W" u2="ó" k="41"/><hkern u1="W" u2="ò" k="41"/><hkern u1="W" u2="ë" k="41"/><hkern u1="W" u2="ê" k="41"/><hkern u1="W" u2="é" k="41"/><hkern u1="W" u2="è" k="41"/><hkern u1="W" u2="ç" k="41"/><hkern u1="W" u2="æ" k="41"/><hkern u1="W" u2="å" k="41"/><hkern u1="W" u2="ä" k="41"/><hkern u1="W" u2="ã" k="41"/><hkern u1="W" u2="â" k="41"/><hkern u1="W" u2="á" k="41"/><hkern u1="W" u2="à" k="41"/><hkern u1="W" u2="Ø" k="20"/><hkern u1="W" u2="Ö" k="20"/><hkern u1="W" u2="Õ" k="20"/><hkern u1="W" u2="Ô" k="20"/><hkern u1="W" u2="Ó" k="20"/><hkern u1="W" u2="Ò" k="20"/><hkern u1="W" u2="Ç" k="20"/><hkern u1="W" u2="Å" k="82"/><hkern u1="W" u2="Ä" k="82"/><hkern u1="W" u2="Ã" k="82"/><hkern u1="W" u2="Â" k="82"/><hkern u1="W" u2="Á" k="82"/><hkern u1="W" u2="À" k="82"/><hkern u1="W" u2="u" k="20"/><hkern u1="W" u2="s" k="20"/><hkern u1="W" u2="r" k="20"/><hkern u1="W" u2="q" k="41"/><hkern u1="W" u2="p" k="20"/><hkern u1="W" u2="o" k="41"/><hkern u1="W" u2="n" k="20"/><hkern u1="W" u2="m" k="20"/><hkern u1="W" u2="g" k="20"/><hkern u1="W" u2="e" k="41"/><hkern u1="W" u2="d" k="41"/><hkern u1="W" u2="c" k="41"/><hkern u1="W" u2="a" k="41"/><hkern u1="W" u2="Q" k="20"/><hkern u1="W" u2="O" k="20"/><hkern u1="W" u2="G" k="20"/><hkern u1="W" u2="C" k="20"/><hkern u1="W" u2="A" k="82"/><hkern u1="W" u2="?" k="-41"/><hkern u1="W" u2="." k="102"/><hkern u1="W" u2="," k="102"/><hkern u1="X" u2="Œ" k="41"/><hkern u1="X" u2="Ø" k="41"/><hkern u1="X" u2="Ö" k="41"/><hkern u1="X" u2="Õ" k="41"/><hkern u1="X" u2="Ô" k="41"/><hkern u1="X" u2="Ó" k="41"/><hkern u1="X" u2="Ò" k="41"/><hkern u1="X" u2="Ç" k="41"/><hkern u1="X" u2="Q" k="41"/><hkern u1="X" u2="O" k="41"/><hkern u1="X" u2="G" k="41"/><hkern u1="X" u2="C" k="41"/><hkern u1="Y" u2="„" k="123"/><hkern u1="Y" u2="‚" k="123"/><hkern u1="Y" u2="œ" k="102"/><hkern u1="Y" u2="Œ" k="41"/><hkern u1="Y" u2="ü" k="61"/><hkern u1="Y" u2="û" k="61"/><hkern u1="Y" u2="ú" k="61"/><hkern u1="Y" u2="ù" k="61"/><hkern u1="Y" u2="ø" k="102"/><hkern u1="Y" u2="ö" k="102"/><hkern u1="Y" u2="õ" k="102"/><hkern u1="Y" u2="ô" k="102"/><hkern u1="Y" u2="ó" k="102"/><hkern u1="Y" u2="ò" k="102"/><hkern u1="Y" u2="ë" k="102"/><hkern u1="Y" u2="ê" k="102"/><hkern u1="Y" u2="é" k="102"/><hkern u1="Y" u2="è" k="102"/><hkern u1="Y" u2="ç" k="102"/><hkern u1="Y" u2="æ" k="102"/><hkern u1="Y" u2="å" k="102"/><hkern u1="Y" u2="ä" k="102"/><hkern u1="Y" u2="ã" k="102"/><hkern u1="Y" u2="â" k="102"/><hkern u1="Y" u2="á" k="102"/><hkern u1="Y" u2="à" k="102"/><hkern u1="Y" u2="Ø" k="41"/><hkern u1="Y" u2="Ö" k="41"/><hkern u1="Y" u2="Õ" k="41"/><hkern u1="Y" u2="Ô" k="41"/><hkern u1="Y" u2="Ó" k="41"/><hkern u1="Y" u2="Ò" k="41"/><hkern u1="Y" u2="Ç" k="41"/><hkern u1="Y" u2="Å" k="123"/><hkern u1="Y" u2="Ä" k="123"/><hkern u1="Y" u2="Ã" k="123"/><hkern u1="Y" u2="Â" k="123"/><hkern u1="Y" u2="Á" k="123"/><hkern u1="Y" u2="À" k="123"/><hkern u1="Y" u2="z" k="41"/><hkern u1="Y" u2="u" k="61"/><hkern u1="Y" u2="s" k="82"/><hkern u1="Y" u2="r" k="61"/><hkern u1="Y" u2="q" k="102"/><hkern u1="Y" u2="p" k="61"/><hkern u1="Y" u2="o" k="102"/><hkern u1="Y" u2="n" k="61"/><hkern u1="Y" u2="m" k="61"/><hkern u1="Y" u2="g" k="41"/><hkern u1="Y" u2="e" k="102"/><hkern u1="Y" u2="d" k="102"/><hkern u1="Y" u2="c" k="102"/><hkern u1="Y" u2="a" k="102"/><hkern u1="Y" u2="Q" k="41"/><hkern u1="Y" u2="O" k="41"/><hkern u1="Y" u2="G" k="41"/><hkern u1="Y" u2="C" k="41"/><hkern u1="Y" u2="A" k="123"/><hkern u1="Y" u2="?" k="-41"/><hkern u1="Y" u2="." k="123"/><hkern u1="Y" u2="," k="123"/><hkern u1="Z" u2="Œ" k="20"/><hkern u1="Z" u2="Ø" k="20"/><hkern u1="Z" u2="Ö" k="20"/><hkern u1="Z" u2="Õ" k="20"/><hkern u1="Z" u2="Ô" k="20"/><hkern u1="Z" u2="Ó" k="20"/><hkern u1="Z" u2="Ò" k="20"/><hkern u1="Z" u2="Ç" k="20"/><hkern u1="Z" u2="Q" k="20"/><hkern u1="Z" u2="O" k="20"/><hkern u1="Z" u2="G" k="20"/><hkern u1="Z" u2="C" k="20"/><hkern u1="[" u2="J" k="-184"/><hkern u1="a" u2="”" k="20"/><hkern u1="a" u2="’" k="20"/><hkern u1="a" u2="'" k="20"/><hkern u1="a" u2="&quot;" k="20"/><hkern u1="b" u2="”" k="20"/><hkern u1="b" u2="’" k="20"/><hkern u1="b" u2="ý" k="41"/><hkern u1="b" u2="z" k="20"/><hkern u1="b" u2="y" k="41"/><hkern u1="b" u2="x" k="41"/><hkern u1="b" u2="w" k="41"/><hkern u1="b" u2="v" k="41"/><hkern u1="b" u2="'" k="20"/><hkern u1="b" u2="&quot;" k="20"/><hkern u1="c" u2="”" k="-41"/><hkern u1="c" u2="’" k="-41"/><hkern u1="c" u2="'" k="-41"/><hkern u1="c" u2="&quot;" k="-41"/><hkern u1="e" u2="”" k="20"/><hkern u1="e" u2="’" k="20"/><hkern u1="e" u2="ý" k="41"/><hkern u1="e" u2="z" k="20"/><hkern u1="e" u2="y" k="41"/><hkern u1="e" u2="x" k="41"/><hkern u1="e" u2="w" k="41"/><hkern u1="e" u2="v" k="41"/><hkern u1="e" u2="'" k="20"/><hkern u1="e" u2="&quot;" k="20"/><hkern u1="f" u2="”" k="-123"/><hkern u1="f" u2="’" k="-123"/><hkern u1="f" u2="'" k="-123"/><hkern u1="f" u2="&quot;" k="-123"/><hkern u1="h" u2="”" k="20"/><hkern u1="h" u2="’" k="20"/><hkern u1="h" u2="'" k="20"/><hkern u1="h" u2="&quot;" k="20"/><hkern u1="k" u2="œ" k="41"/><hkern u1="k" u2="ø" k="41"/><hkern u1="k" u2="ö" k="41"/><hkern u1="k" u2="õ" k="41"/><hkern u1="k" u2="ô" k="41"/><hkern u1="k" u2="ó" k="41"/><hkern u1="k" u2="ò" k="41"/><hkern u1="k" u2="ë" k="41"/><hkern u1="k" u2="ê" k="41"/><hkern u1="k" u2="é" k="41"/><hkern u1="k" u2="è" k="41"/><hkern u1="k" u2="ç" k="41"/><hkern u1="k" u2="à" k="41"/><hkern u1="k" u2="q" k="41"/><hkern u1="k" u2="o" k="41"/><hkern u1="k" u2="e" k="41"/><hkern u1="k" u2="d" k="41"/><hkern u1="k" u2="c" k="41"/><hkern u1="m" u2="”" k="20"/><hkern u1="m" u2="’" k="20"/><hkern u1="m" u2="'" k="20"/><hkern u1="m" u2="&quot;" k="20"/><hkern u1="n" u2="”" k="20"/><hkern u1="n" u2="’" k="20"/><hkern u1="n" u2="'" k="20"/><hkern u1="n" u2="&quot;" k="20"/><hkern u1="o" u2="”" k="20"/><hkern u1="o" u2="’" k="20"/><hkern u1="o" u2="ý" k="41"/><hkern u1="o" u2="z" k="20"/><hkern u1="o" u2="y" k="41"/><hkern u1="o" u2="x" k="41"/><hkern u1="o" u2="w" k="41"/><hkern u1="o" u2="v" k="41"/><hkern u1="o" u2="'" k="20"/><hkern u1="o" u2="&quot;" k="20"/><hkern u1="p" u2="”" k="20"/><hkern u1="p" u2="’" k="20"/><hkern u1="p" u2="ý" k="41"/><hkern u1="p" u2="z" k="20"/><hkern u1="p" u2="y" k="41"/><hkern u1="p" u2="x" k="41"/><hkern u1="p" u2="w" k="41"/><hkern u1="p" u2="v" k="41"/><hkern u1="p" u2="'" k="20"/><hkern u1="p" u2="&quot;" k="20"/><hkern u1="r" u2="”" k="-82"/><hkern u1="r" u2="’" k="-82"/><hkern u1="r" u2="œ" k="41"/><hkern u1="r" u2="ø" k="41"/><hkern u1="r" u2="ö" k="41"/><hkern u1="r" u2="õ" k="41"/><hkern u1="r" u2="ô" k="41"/><hkern u1="r" u2="ó" k="41"/><hkern u1="r" u2="ò" k="41"/><hkern u1="r" u2="ë" k="41"/><hkern u1="r" u2="ê" k="41"/><hkern u1="r" u2="é" k="41"/><hkern u1="r" u2="è" k="41"/><hkern u1="r" u2="ç" k="41"/><hkern u1="r" u2="æ" k="41"/><hkern u1="r" u2="å" k="41"/><hkern u1="r" u2="ä" k="41"/><hkern u1="r" u2="ã" k="41"/><hkern u1="r" u2="â" k="41"/><hkern u1="r" u2="á" k="41"/><hkern u1="r" u2="à" k="41"/><hkern u1="r" u2="q" k="41"/><hkern u1="r" u2="o" k="41"/><hkern u1="r" u2="g" k="20"/><hkern u1="r" u2="e" k="41"/><hkern u1="r" u2="d" k="41"/><hkern u1="r" u2="c" k="41"/><hkern u1="r" u2="a" k="41"/><hkern u1="r" u2="'" k="-82"/><hkern u1="r" u2="&quot;" k="-82"/><hkern u1="t" u2="”" k="-41"/><hkern u1="t" u2="’" k="-41"/><hkern u1="t" u2="'" k="-41"/><hkern u1="t" u2="&quot;" k="-41"/><hkern u1="v" u2="„" k="82"/><hkern u1="v" u2="”" k="-82"/><hkern u1="v" u2="‚" k="82"/><hkern u1="v" u2="’" k="-82"/><hkern u1="v" u2="?" k="-41"/><hkern u1="v" u2="." k="82"/><hkern u1="v" u2="," k="82"/><hkern u1="v" u2="'" k="-82"/><hkern u1="v" u2="&quot;" k="-82"/><hkern u1="w" u2="„" k="82"/><hkern u1="w" u2="”" k="-82"/><hkern u1="w" u2="‚" k="82"/><hkern u1="w" u2="’" k="-82"/><hkern u1="w" u2="?" k="-41"/><hkern u1="w" u2="." k="82"/><hkern u1="w" u2="," k="82"/><hkern u1="w" u2="'" k="-82"/><hkern u1="w" u2="&quot;" k="-82"/><hkern u1="x" u2="œ" k="41"/><hkern u1="x" u2="ø" k="41"/><hkern u1="x" u2="ö" k="41"/><hkern u1="x" u2="õ" k="41"/><hkern u1="x" u2="ô" k="41"/><hkern u1="x" u2="ó" k="41"/><hkern u1="x" u2="ò" k="41"/><hkern u1="x" u2="ë" k="41"/><hkern u1="x" u2="ê" k="41"/><hkern u1="x" u2="é" k="41"/><hkern u1="x" u2="è" k="41"/><hkern u1="x" u2="ç" k="41"/><hkern u1="x" u2="à" k="41"/><hkern u1="x" u2="q" k="41"/><hkern u1="x" u2="o" k="41"/><hkern u1="x" u2="e" k="41"/><hkern u1="x" u2="d" k="41"/><hkern u1="x" u2="c" k="41"/><hkern u1="y" u2="„" k="82"/><hkern u1="y" u2="”" k="-82"/><hkern u1="y" u2="‚" k="82"/><hkern u1="y" u2="’" k="-82"/><hkern u1="y" u2="?" k="-41"/><hkern u1="y" u2="." k="82"/><hkern u1="y" u2="," k="82"/><hkern u1="y" u2="'" k="-82"/><hkern u1="y" u2="&quot;" k="-82"/><hkern u1="{" u2="J" k="-184"/><hkern u1="À" u2="”" k="143"/><hkern u1="À" u2="’" k="143"/><hkern u1="À" u2="Ÿ" k="123"/><hkern u1="À" u2="Œ" k="41"/><hkern u1="À" u2="Ý" k="123"/><hkern u1="À" u2="Ø" k="41"/><hkern u1="À" u2="Ö" k="41"/><hkern u1="À" u2="Õ" k="41"/><hkern u1="À" u2="Ô" k="41"/><hkern u1="À" u2="Ó" k="41"/><hkern u1="À" u2="Ò" k="41"/><hkern u1="À" u2="Ç" k="41"/><hkern u1="À" u2="Y" k="123"/><hkern u1="À" u2="W" k="82"/><hkern u1="À" u2="V" k="82"/><hkern u1="À" u2="T" k="143"/><hkern u1="À" u2="Q" k="41"/><hkern u1="À" u2="O" k="41"/><hkern u1="À" u2="J" k="-266"/><hkern u1="À" u2="G" k="41"/><hkern u1="À" u2="C" k="41"/><hkern u1="À" u2="'" k="143"/><hkern u1="À" u2="&quot;" k="143"/><hkern u1="Á" u2="”" k="143"/><hkern u1="Á" u2="’" k="143"/><hkern u1="Á" u2="Ÿ" k="123"/><hkern u1="Á" u2="Œ" k="41"/><hkern u1="Á" u2="Ý" k="123"/><hkern u1="Á" u2="Ø" k="41"/><hkern u1="Á" u2="Ö" k="41"/><hkern u1="Á" u2="Õ" k="41"/><hkern u1="Á" u2="Ô" k="41"/><hkern u1="Á" u2="Ó" k="41"/><hkern u1="Á" u2="Ò" k="41"/><hkern u1="Á" u2="Ç" k="41"/><hkern u1="Á" u2="Y" k="123"/><hkern u1="Á" u2="W" k="82"/><hkern u1="Á" u2="V" k="82"/><hkern u1="Á" u2="T" k="143"/><hkern u1="Á" u2="Q" k="41"/><hkern u1="Á" u2="O" k="41"/><hkern u1="Á" u2="J" k="-266"/><hkern u1="Á" u2="G" k="41"/><hkern u1="Á" u2="C" k="41"/><hkern u1="Á" u2="'" k="143"/><hkern u1="Á" u2="&quot;" k="143"/><hkern u1="Â" u2="”" k="143"/><hkern u1="Â" u2="’" k="143"/><hkern u1="Â" u2="Ÿ" k="123"/><hkern u1="Â" u2="Œ" k="41"/><hkern u1="Â" u2="Ý" k="123"/><hkern u1="Â" u2="Ø" k="41"/><hkern u1="Â" u2="Ö" k="41"/><hkern u1="Â" u2="Õ" k="41"/><hkern u1="Â" u2="Ô" k="41"/><hkern u1="Â" u2="Ó" k="41"/><hkern u1="Â" u2="Ò" k="41"/><hkern u1="Â" u2="Ç" k="41"/><hkern u1="Â" u2="Y" k="123"/><hkern u1="Â" u2="W" k="82"/><hkern u1="Â" u2="V" k="82"/><hkern u1="Â" u2="T" k="143"/><hkern u1="Â" u2="Q" k="41"/><hkern u1="Â" u2="O" k="41"/><hkern u1="Â" u2="J" k="-266"/><hkern u1="Â" u2="G" k="41"/><hkern u1="Â" u2="C" k="41"/><hkern u1="Â" u2="'" k="143"/><hkern u1="Â" u2="&quot;" k="143"/><hkern u1="Ã" u2="”" k="143"/><hkern u1="Ã" u2="’" k="143"/><hkern u1="Ã" u2="Ÿ" k="123"/><hkern u1="Ã" u2="Œ" k="41"/><hkern u1="Ã" u2="Ý" k="123"/><hkern u1="Ã" u2="Ø" k="41"/><hkern u1="Ã" u2="Ö" k="41"/><hkern u1="Ã" u2="Õ" k="41"/><hkern u1="Ã" u2="Ô" k="41"/><hkern u1="Ã" u2="Ó" k="41"/><hkern u1="Ã" u2="Ò" k="41"/><hkern u1="Ã" u2="Ç" k="41"/><hkern u1="Ã" u2="Y" k="123"/><hkern u1="Ã" u2="W" k="82"/><hkern u1="Ã" u2="V" k="82"/><hkern u1="Ã" u2="T" k="143"/><hkern u1="Ã" u2="Q" k="41"/><hkern u1="Ã" u2="O" k="41"/><hkern u1="Ã" u2="J" k="-266"/><hkern u1="Ã" u2="G" k="41"/><hkern u1="Ã" u2="C" k="41"/><hkern u1="Ã" u2="'" k="143"/><hkern u1="Ã" u2="&quot;" k="143"/><hkern u1="Ä" u2="”" k="143"/><hkern u1="Ä" u2="’" k="143"/><hkern u1="Ä" u2="Ÿ" k="123"/><hkern u1="Ä" u2="Œ" k="41"/><hkern u1="Ä" u2="Ý" k="123"/><hkern u1="Ä" u2="Ø" k="41"/><hkern u1="Ä" u2="Ö" k="41"/><hkern u1="Ä" u2="Õ" k="41"/><hkern u1="Ä" u2="Ô" k="41"/><hkern u1="Ä" u2="Ó" k="41"/><hkern u1="Ä" u2="Ò" k="41"/><hkern u1="Ä" u2="Ç" k="41"/><hkern u1="Ä" u2="Y" k="123"/><hkern u1="Ä" u2="W" k="82"/><hkern u1="Ä" u2="V" k="82"/><hkern u1="Ä" u2="T" k="143"/><hkern u1="Ä" u2="Q" k="41"/><hkern u1="Ä" u2="O" k="41"/><hkern u1="Ä" u2="J" k="-266"/><hkern u1="Ä" u2="G" k="41"/><hkern u1="Ä" u2="C" k="41"/><hkern u1="Ä" u2="'" k="143"/><hkern u1="Ä" u2="&quot;" k="143"/><hkern u1="Å" u2="”" k="143"/><hkern u1="Å" u2="’" k="143"/><hkern u1="Å" u2="Ÿ" k="123"/><hkern u1="Å" u2="Œ" k="41"/><hkern u1="Å" u2="Ý" k="123"/><hkern u1="Å" u2="Ø" k="41"/><hkern u1="Å" u2="Ö" k="41"/><hkern u1="Å" u2="Õ" k="41"/><hkern u1="Å" u2="Ô" k="41"/><hkern u1="Å" u2="Ó" k="41"/><hkern u1="Å" u2="Ò" k="41"/><hkern u1="Å" u2="Ç" k="41"/><hkern u1="Å" u2="Y" k="123"/><hkern u1="Å" u2="W" k="82"/><hkern u1="Å" u2="V" k="82"/><hkern u1="Å" u2="T" k="143"/><hkern u1="Å" u2="Q" k="41"/><hkern u1="Å" u2="O" k="41"/><hkern u1="Å" u2="J" k="-266"/><hkern u1="Å" u2="G" k="41"/><hkern u1="Å" u2="C" k="41"/><hkern u1="Å" u2="'" k="143"/><hkern u1="Å" u2="&quot;" k="143"/><hkern u1="Æ" u2="J" k="-123"/><hkern u1="Ç" u2="Œ" k="41"/><hkern u1="Ç" u2="Ø" k="41"/><hkern u1="Ç" u2="Ö" k="41"/><hkern u1="Ç" u2="Õ" k="41"/><hkern u1="Ç" u2="Ô" k="41"/><hkern u1="Ç" u2="Ó" k="41"/><hkern u1="Ç" u2="Ò" k="41"/><hkern u1="Ç" u2="Ç" k="41"/><hkern u1="Ç" u2="Q" k="41"/><hkern u1="Ç" u2="O" k="41"/><hkern u1="Ç" u2="G" k="41"/><hkern u1="Ç" u2="C" k="41"/><hkern u1="È" u2="J" k="-123"/><hkern u1="É" u2="J" k="-123"/><hkern u1="Ê" u2="J" k="-123"/><hkern u1="Ë" u2="J" k="-123"/><hkern u1="Ð" u2="„" k="82"/><hkern u1="Ð" u2="‚" k="82"/><hkern u1="Ð" u2="Ÿ" k="20"/><hkern u1="Ð" u2="Ý" k="20"/><hkern u1="Ð" u2="Å" k="41"/><hkern u1="Ð" u2="Ä" k="41"/><hkern u1="Ð" u2="Ã" k="41"/><hkern u1="Ð" u2="Â" k="41"/><hkern u1="Ð" u2="Á" k="41"/><hkern u1="Ð" u2="À" k="41"/><hkern u1="Ð" u2="Z" k="20"/><hkern u1="Ð" u2="Y" k="20"/><hkern u1="Ð" u2="X" k="41"/><hkern u1="Ð" u2="W" k="20"/><hkern u1="Ð" u2="V" k="20"/><hkern u1="Ð" u2="T" k="61"/><hkern u1="Ð" u2="A" k="41"/><hkern u1="Ð" u2="." k="82"/><hkern u1="Ð" u2="," k="82"/><hkern u1="Ò" u2="„" k="82"/><hkern u1="Ò" u2="‚" k="82"/><hkern u1="Ò" u2="Ÿ" k="20"/><hkern u1="Ò" u2="Ý" k="20"/><hkern u1="Ò" u2="Å" k="41"/><hkern u1="Ò" u2="Ä" k="41"/><hkern u1="Ò" u2="Ã" k="41"/><hkern u1="Ò" u2="Â" k="41"/><hkern u1="Ò" u2="Á" k="41"/><hkern u1="Ò" u2="À" k="41"/><hkern u1="Ò" u2="Z" k="20"/><hkern u1="Ò" u2="Y" k="20"/><hkern u1="Ò" u2="X" k="41"/><hkern u1="Ò" u2="W" k="20"/><hkern u1="Ò" u2="V" k="20"/><hkern u1="Ò" u2="T" k="61"/><hkern u1="Ò" u2="A" k="41"/><hkern u1="Ò" u2="." k="82"/><hkern u1="Ò" u2="," k="82"/><hkern u1="Ó" u2="„" k="82"/><hkern u1="Ó" u2="‚" k="82"/><hkern u1="Ó" u2="Ÿ" k="20"/><hkern u1="Ó" u2="Ý" k="20"/><hkern u1="Ó" u2="Å" k="41"/><hkern u1="Ó" u2="Ä" k="41"/><hkern u1="Ó" u2="Ã" k="41"/><hkern u1="Ó" u2="Â" k="41"/><hkern u1="Ó" u2="Á" k="41"/><hkern u1="Ó" u2="À" k="41"/><hkern u1="Ó" u2="Z" k="20"/><hkern u1="Ó" u2="Y" k="20"/><hkern u1="Ó" u2="X" k="41"/><hkern u1="Ó" u2="W" k="20"/><hkern u1="Ó" u2="V" k="20"/><hkern u1="Ó" u2="T" k="61"/><hkern u1="Ó" u2="A" k="41"/><hkern u1="Ó" u2="." k="82"/><hkern u1="Ó" u2="," k="82"/><hkern u1="Ô" u2="„" k="82"/><hkern u1="Ô" u2="‚" k="82"/><hkern u1="Ô" u2="Ÿ" k="20"/><hkern u1="Ô" u2="Ý" k="20"/><hkern u1="Ô" u2="Å" k="41"/><hkern u1="Ô" u2="Ä" k="41"/><hkern u1="Ô" u2="Ã" k="41"/><hkern u1="Ô" u2="Â" k="41"/><hkern u1="Ô" u2="Á" k="41"/><hkern u1="Ô" u2="À" k="41"/><hkern u1="Ô" u2="Z" k="20"/><hkern u1="Ô" u2="Y" k="20"/><hkern u1="Ô" u2="X" k="41"/><hkern u1="Ô" u2="W" k="20"/><hkern u1="Ô" u2="V" k="20"/><hkern u1="Ô" u2="T" k="61"/><hkern u1="Ô" u2="A" k="41"/><hkern u1="Ô" u2="." k="82"/><hkern u1="Ô" u2="," k="82"/><hkern u1="Õ" u2="„" k="82"/><hkern u1="Õ" u2="‚" k="82"/><hkern u1="Õ" u2="Ÿ" k="20"/><hkern u1="Õ" u2="Ý" k="20"/><hkern u1="Õ" u2="Å" k="41"/><hkern u1="Õ" u2="Ä" k="41"/><hkern u1="Õ" u2="Ã" k="41"/><hkern u1="Õ" u2="Â" k="41"/><hkern u1="Õ" u2="Á" k="41"/><hkern u1="Õ" u2="À" k="41"/><hkern u1="Õ" u2="Z" k="20"/><hkern u1="Õ" u2="Y" k="20"/><hkern u1="Õ" u2="X" k="41"/><hkern u1="Õ" u2="W" k="20"/><hkern u1="Õ" u2="V" k="20"/><hkern u1="Õ" u2="T" k="61"/><hkern u1="Õ" u2="A" k="41"/><hkern u1="Õ" u2="." k="82"/><hkern u1="Õ" u2="," k="82"/><hkern u1="Ö" u2="„" k="82"/><hkern u1="Ö" u2="‚" k="82"/><hkern u1="Ö" u2="Ÿ" k="20"/><hkern u1="Ö" u2="Ý" k="20"/><hkern u1="Ö" u2="Å" k="41"/><hkern u1="Ö" u2="Ä" k="41"/><hkern u1="Ö" u2="Ã" k="41"/><hkern u1="Ö" u2="Â" k="41"/><hkern u1="Ö" u2="Á" k="41"/><hkern u1="Ö" u2="À" k="41"/><hkern u1="Ö" u2="Z" k="20"/><hkern u1="Ö" u2="Y" k="20"/><hkern u1="Ö" u2="X" k="41"/><hkern u1="Ö" u2="W" k="20"/><hkern u1="Ö" u2="V" k="20"/><hkern u1="Ö" u2="T" k="61"/><hkern u1="Ö" u2="A" k="41"/><hkern u1="Ö" u2="." k="82"/><hkern u1="Ö" u2="," k="82"/><hkern u1="Ø" u2="„" k="82"/><hkern u1="Ø" u2="‚" k="82"/><hkern u1="Ø" u2="Ÿ" k="20"/><hkern u1="Ø" u2="Ý" k="20"/><hkern u1="Ø" u2="Å" k="41"/><hkern u1="Ø" u2="Ä" k="41"/><hkern u1="Ø" u2="Ã" k="41"/><hkern u1="Ø" u2="Â" k="41"/><hkern u1="Ø" u2="Á" k="41"/><hkern u1="Ø" u2="À" k="41"/><hkern u1="Ø" u2="Z" k="20"/><hkern u1="Ø" u2="Y" k="20"/><hkern u1="Ø" u2="X" k="41"/><hkern u1="Ø" u2="W" k="20"/><hkern u1="Ø" u2="V" k="20"/><hkern u1="Ø" u2="T" k="61"/><hkern u1="Ø" u2="A" k="41"/><hkern u1="Ø" u2="." k="82"/><hkern u1="Ø" u2="," k="82"/><hkern u1="Ù" u2="„" k="41"/><hkern u1="Ù" u2="‚" k="41"/><hkern u1="Ù" u2="Å" k="20"/><hkern u1="Ù" u2="Ä" k="20"/><hkern u1="Ù" u2="Ã" k="20"/><hkern u1="Ù" u2="Â" k="20"/><hkern u1="Ù" u2="Á" k="20"/><hkern u1="Ù" u2="À" k="20"/><hkern u1="Ù" u2="A" k="20"/><hkern u1="Ù" u2="." k="41"/><hkern u1="Ù" u2="," k="41"/><hkern u1="Ú" u2="„" k="41"/><hkern u1="Ú" u2="‚" k="41"/><hkern u1="Ú" u2="Å" k="20"/><hkern u1="Ú" u2="Ä" k="20"/><hkern u1="Ú" u2="Ã" k="20"/><hkern u1="Ú" u2="Â" k="20"/><hkern u1="Ú" u2="Á" k="20"/><hkern u1="Ú" u2="À" k="20"/><hkern u1="Ú" u2="A" k="20"/><hkern u1="Ú" u2="." k="41"/><hkern u1="Ú" u2="," k="41"/><hkern u1="Û" u2="„" k="41"/><hkern u1="Û" u2="‚" k="41"/><hkern u1="Û" u2="Å" k="20"/><hkern u1="Û" u2="Ä" k="20"/><hkern u1="Û" u2="Ã" k="20"/><hkern u1="Û" u2="Â" k="20"/><hkern u1="Û" u2="Á" k="20"/><hkern u1="Û" u2="À" k="20"/><hkern u1="Û" u2="A" k="20"/><hkern u1="Û" u2="." k="41"/><hkern u1="Û" u2="," k="41"/><hkern u1="Ü" u2="„" k="41"/><hkern u1="Ü" u2="‚" k="41"/><hkern u1="Ü" u2="Å" k="20"/><hkern u1="Ü" u2="Ä" k="20"/><hkern u1="Ü" u2="Ã" k="20"/><hkern u1="Ü" u2="Â" k="20"/><hkern u1="Ü" u2="Á" k="20"/><hkern u1="Ü" u2="À" k="20"/><hkern u1="Ü" u2="A" k="20"/><hkern u1="Ü" u2="." k="41"/><hkern u1="Ü" u2="," k="41"/><hkern u1="Ý" u2="„" k="123"/><hkern u1="Ý" u2="‚" k="123"/><hkern u1="Ý" u2="œ" k="102"/><hkern u1="Ý" u2="Œ" k="41"/><hkern u1="Ý" u2="ü" k="61"/><hkern u1="Ý" u2="û" k="61"/><hkern u1="Ý" u2="ú" k="61"/><hkern u1="Ý" u2="ù" k="61"/><hkern u1="Ý" u2="ø" k="102"/><hkern u1="Ý" u2="ö" k="102"/><hkern u1="Ý" u2="õ" k="102"/><hkern u1="Ý" u2="ô" k="102"/><hkern u1="Ý" u2="ó" k="102"/><hkern u1="Ý" u2="ò" k="102"/><hkern u1="Ý" u2="ë" k="102"/><hkern u1="Ý" u2="ê" k="102"/><hkern u1="Ý" u2="é" k="102"/><hkern u1="Ý" u2="è" k="102"/><hkern u1="Ý" u2="ç" k="102"/><hkern u1="Ý" u2="æ" k="102"/><hkern u1="Ý" u2="å" k="102"/><hkern u1="Ý" u2="ä" k="102"/><hkern u1="Ý" u2="ã" k="102"/><hkern u1="Ý" u2="â" k="102"/><hkern u1="Ý" u2="á" k="102"/><hkern u1="Ý" u2="à" k="102"/><hkern u1="Ý" u2="Ø" k="41"/><hkern u1="Ý" u2="Ö" k="41"/><hkern u1="Ý" u2="Õ" k="41"/><hkern u1="Ý" u2="Ô" k="41"/><hkern u1="Ý" u2="Ó" k="41"/><hkern u1="Ý" u2="Ò" k="41"/><hkern u1="Ý" u2="Ç" k="41"/><hkern u1="Ý" u2="Å" k="123"/><hkern u1="Ý" u2="Ä" k="123"/><hkern u1="Ý" u2="Ã" k="123"/><hkern u1="Ý" u2="Â" k="123"/><hkern u1="Ý" u2="Á" k="123"/><hkern u1="Ý" u2="À" k="123"/><hkern u1="Ý" u2="z" k="41"/><hkern u1="Ý" u2="u" k="61"/><hkern u1="Ý" u2="s" k="82"/><hkern u1="Ý" u2="r" k="61"/><hkern u1="Ý" u2="q" k="102"/><hkern u1="Ý" u2="p" k="61"/><hkern u1="Ý" u2="o" k="102"/><hkern u1="Ý" u2="n" k="61"/><hkern u1="Ý" u2="m" k="61"/><hkern u1="Ý" u2="g" k="41"/><hkern u1="Ý" u2="e" k="102"/><hkern u1="Ý" u2="d" k="102"/><hkern u1="Ý" u2="c" k="102"/><hkern u1="Ý" u2="a" k="102"/><hkern u1="Ý" u2="Q" k="41"/><hkern u1="Ý" u2="O" k="41"/><hkern u1="Ý" u2="G" k="41"/><hkern u1="Ý" u2="C" k="41"/><hkern u1="Ý" u2="A" k="123"/><hkern u1="Ý" u2="?" k="-41"/><hkern u1="Ý" u2="." k="123"/><hkern u1="Ý" u2="," k="123"/><hkern u1="Þ" u2="„" k="266"/><hkern u1="Þ" u2="‚" k="266"/><hkern u1="Þ" u2="Å" k="102"/><hkern u1="Þ" u2="Ä" k="102"/><hkern u1="Þ" u2="Ã" k="102"/><hkern u1="Þ" u2="Â" k="102"/><hkern u1="Þ" u2="Á" k="102"/><hkern u1="Þ" u2="À" k="102"/><hkern u1="Þ" u2="Z" k="20"/><hkern u1="Þ" u2="X" k="41"/><hkern u1="Þ" u2="A" k="102"/><hkern u1="Þ" u2="." k="266"/><hkern u1="Þ" u2="," k="266"/><hkern u1="à" u2="”" k="20"/><hkern u1="à" u2="’" k="20"/><hkern u1="à" u2="'" k="20"/><hkern u1="à" u2="&quot;" k="20"/><hkern u1="á" u2="”" k="20"/><hkern u1="á" u2="’" k="20"/><hkern u1="á" u2="'" k="20"/><hkern u1="á" u2="&quot;" k="20"/><hkern u1="â" u2="”" k="20"/><hkern u1="â" u2="’" k="20"/><hkern u1="â" u2="'" k="20"/><hkern u1="â" u2="&quot;" k="20"/><hkern u1="ã" u2="”" k="20"/><hkern u1="ã" u2="’" k="20"/><hkern u1="ã" u2="'" k="20"/><hkern u1="ã" u2="&quot;" k="20"/><hkern u1="ä" u2="”" k="20"/><hkern u1="ä" u2="’" k="20"/><hkern u1="ä" u2="'" k="20"/><hkern u1="ä" u2="&quot;" k="20"/><hkern u1="å" u2="”" k="20"/><hkern u1="å" u2="’" k="20"/><hkern u1="å" u2="'" k="20"/><hkern u1="å" u2="&quot;" k="20"/><hkern u1="è" u2="”" k="20"/><hkern u1="è" u2="’" k="20"/><hkern u1="è" u2="ý" k="41"/><hkern u1="è" u2="z" k="20"/><hkern u1="è" u2="y" k="41"/><hkern u1="è" u2="x" k="41"/><hkern u1="è" u2="w" k="41"/><hkern u1="è" u2="v" k="41"/><hkern u1="è" u2="'" k="20"/><hkern u1="è" u2="&quot;" k="20"/><hkern u1="é" u2="”" k="20"/><hkern u1="é" u2="’" k="20"/><hkern u1="é" u2="ý" k="41"/><hkern u1="é" u2="z" k="20"/><hkern u1="é" u2="y" k="41"/><hkern u1="é" u2="x" k="41"/><hkern u1="é" u2="w" k="41"/><hkern u1="é" u2="v" k="41"/><hkern u1="é" u2="'" k="20"/><hkern u1="é" u2="&quot;" k="20"/><hkern u1="ê" u2="”" k="20"/><hkern u1="ê" u2="’" k="20"/><hkern u1="ê" u2="ý" k="41"/><hkern u1="ê" u2="z" k="20"/><hkern u1="ê" u2="y" k="41"/><hkern u1="ê" u2="x" k="41"/><hkern u1="ê" u2="w" k="41"/><hkern u1="ê" u2="v" k="41"/><hkern u1="ê" u2="'" k="20"/><hkern u1="ê" u2="&quot;" k="20"/><hkern u1="ë" u2="”" k="20"/><hkern u1="ë" u2="’" k="20"/><hkern u1="ë" u2="ý" k="41"/><hkern u1="ë" u2="z" k="20"/><hkern u1="ë" u2="y" k="41"/><hkern u1="ë" u2="x" k="41"/><hkern u1="ë" u2="w" k="41"/><hkern u1="ë" u2="v" k="41"/><hkern u1="ë" u2="'" k="20"/><hkern u1="ë" u2="&quot;" k="20"/><hkern u1="ð" u2="”" k="20"/><hkern u1="ð" u2="’" k="20"/><hkern u1="ð" u2="ý" k="41"/><hkern u1="ð" u2="z" k="20"/><hkern u1="ð" u2="y" k="41"/><hkern u1="ð" u2="x" k="41"/><hkern u1="ð" u2="w" k="41"/><hkern u1="ð" u2="v" k="41"/><hkern u1="ð" u2="'" k="20"/><hkern u1="ð" u2="&quot;" k="20"/><hkern u1="ò" u2="”" k="20"/><hkern u1="ò" u2="’" k="20"/><hkern u1="ò" u2="ý" k="41"/><hkern u1="ò" u2="z" k="20"/><hkern u1="ò" u2="y" k="41"/><hkern u1="ò" u2="x" k="41"/><hkern u1="ò" u2="w" k="41"/><hkern u1="ò" u2="v" k="41"/><hkern u1="ò" u2="'" k="20"/><hkern u1="ò" u2="&quot;" k="20"/><hkern u1="ó" u2="”" k="20"/><hkern u1="ó" u2="’" k="20"/><hkern u1="ó" u2="ý" k="41"/><hkern u1="ó" u2="z" k="20"/><hkern u1="ó" u2="y" k="41"/><hkern u1="ó" u2="x" k="41"/><hkern u1="ó" u2="w" k="41"/><hkern u1="ó" u2="v" k="41"/><hkern u1="ó" u2="'" k="20"/><hkern u1="ó" u2="&quot;" k="20"/><hkern u1="ô" u2="”" k="20"/><hkern u1="ô" u2="’" k="20"/><hkern u1="ô" u2="ý" k="41"/><hkern u1="ô" u2="z" k="20"/><hkern u1="ô" u2="y" k="41"/><hkern u1="ô" u2="x" k="41"/><hkern u1="ô" u2="w" k="41"/><hkern u1="ô" u2="v" k="41"/><hkern u1="ô" u2="'" k="20"/><hkern u1="ô" u2="&quot;" k="20"/><hkern u1="ö" u2="”" k="41"/><hkern u1="ö" u2="’" k="41"/><hkern u1="ö" u2="'" k="41"/><hkern u1="ö" u2="&quot;" k="41"/><hkern u1="ø" u2="”" k="20"/><hkern u1="ø" u2="’" k="20"/><hkern u1="ø" u2="ý" k="41"/><hkern u1="ø" u2="z" k="20"/><hkern u1="ø" u2="y" k="41"/><hkern u1="ø" u2="x" k="41"/><hkern u1="ø" u2="w" k="41"/><hkern u1="ø" u2="v" k="41"/><hkern u1="ø" u2="'" k="20"/><hkern u1="ø" u2="&quot;" k="20"/><hkern u1="ý" u2="„" k="82"/><hkern u1="ý" u2="”" k="-82"/><hkern u1="ý" u2="‚" k="82"/><hkern u1="ý" u2="’" k="-82"/><hkern u1="ý" u2="?" k="-41"/><hkern u1="ý" u2="." k="82"/><hkern u1="ý" u2="," k="82"/><hkern u1="ý" u2="'" k="-82"/><hkern u1="ý" u2="&quot;" k="-82"/><hkern u1="þ" u2="”" k="20"/><hkern u1="þ" u2="’" k="20"/><hkern u1="þ" u2="ý" k="41"/><hkern u1="þ" u2="z" k="20"/><hkern u1="þ" u2="y" k="41"/><hkern u1="þ" u2="x" k="41"/><hkern u1="þ" u2="w" k="41"/><hkern u1="þ" u2="v" k="41"/><hkern u1="þ" u2="'" k="20"/><hkern u1="þ" u2="&quot;" k="20"/><hkern u1="ÿ" u2="„" k="82"/><hkern u1="ÿ" u2="”" k="-82"/><hkern u1="ÿ" u2="‚" k="82"/><hkern u1="ÿ" u2="’" k="-82"/><hkern u1="ÿ" u2="?" k="-41"/><hkern u1="ÿ" u2="." k="82"/><hkern u1="ÿ" u2="," k="82"/><hkern u1="ÿ" u2="'" k="-82"/><hkern u1="ÿ" u2="&quot;" k="-82"/><hkern u1="Œ" u2="J" k="-123"/><hkern u1="Ÿ" u2="„" k="123"/><hkern u1="Ÿ" u2="‚" k="123"/><hkern u1="Ÿ" u2="œ" k="102"/><hkern u1="Ÿ" u2="Œ" k="41"/><hkern u1="Ÿ" u2="ü" k="61"/><hkern u1="Ÿ" u2="û" k="61"/><hkern u1="Ÿ" u2="ú" k="61"/><hkern u1="Ÿ" u2="ù" k="61"/><hkern u1="Ÿ" u2="ø" k="102"/><hkern u1="Ÿ" u2="ö" k="102"/><hkern u1="Ÿ" u2="õ" k="102"/><hkern u1="Ÿ" u2="ô" k="102"/><hkern u1="Ÿ" u2="ó" k="102"/><hkern u1="Ÿ" u2="ò" k="102"/><hkern u1="Ÿ" u2="ë" k="102"/><hkern u1="Ÿ" u2="ê" k="102"/><hkern u1="Ÿ" u2="é" k="102"/><hkern u1="Ÿ" u2="è" k="102"/><hkern u1="Ÿ" u2="ç" k="102"/><hkern u1="Ÿ" u2="æ" k="102"/><hkern u1="Ÿ" u2="å" k="102"/><hkern u1="Ÿ" u2="ä" k="102"/><hkern u1="Ÿ" u2="ã" k="102"/><hkern u1="Ÿ" u2="â" k="102"/><hkern u1="Ÿ" u2="á" k="102"/><hkern u1="Ÿ" u2="à" k="102"/><hkern u1="Ÿ" u2="Ø" k="41"/><hkern u1="Ÿ" u2="Ö" k="41"/><hkern u1="Ÿ" u2="Õ" k="41"/><hkern u1="Ÿ" u2="Ô" k="41"/><hkern u1="Ÿ" u2="Ó" k="41"/><hkern u1="Ÿ" u2="Ò" k="41"/><hkern u1="Ÿ" u2="Ç" k="41"/><hkern u1="Ÿ" u2="Å" k="123"/><hkern u1="Ÿ" u2="Ä" k="123"/><hkern u1="Ÿ" u2="Ã" k="123"/><hkern u1="Ÿ" u2="Â" k="123"/><hkern u1="Ÿ" u2="Á" k="123"/><hkern u1="Ÿ" u2="À" k="123"/><hkern u1="Ÿ" u2="z" k="41"/><hkern u1="Ÿ" u2="u" k="61"/><hkern u1="Ÿ" u2="s" k="82"/><hkern u1="Ÿ" u2="r" k="61"/><hkern u1="Ÿ" u2="q" k="102"/><hkern u1="Ÿ" u2="p" k="61"/><hkern u1="Ÿ" u2="o" k="102"/><hkern u1="Ÿ" u2="n" k="61"/><hkern u1="Ÿ" u2="m" k="61"/><hkern u1="Ÿ" u2="g" k="41"/><hkern u1="Ÿ" u2="e" k="102"/><hkern u1="Ÿ" u2="d" k="102"/><hkern u1="Ÿ" u2="c" k="102"/><hkern u1="Ÿ" u2="a" k="102"/><hkern u1="Ÿ" u2="Q" k="41"/><hkern u1="Ÿ" u2="O" k="41"/><hkern u1="Ÿ" u2="G" k="41"/><hkern u1="Ÿ" u2="C" k="41"/><hkern u1="Ÿ" u2="A" k="123"/><hkern u1="Ÿ" u2="?" k="-41"/><hkern u1="Ÿ" u2="." k="123"/><hkern u1="Ÿ" u2="," k="123"/><hkern u1="–" u2="T" k="82"/><hkern u1="—" u2="T" k="82"/><hkern u1="‘" u2="Ÿ" k="-20"/><hkern u1="‘" u2="œ" k="123"/><hkern u1="‘" u2="ü" k="61"/><hkern u1="‘" u2="û" k="61"/><hkern u1="‘" u2="ú" k="61"/><hkern u1="‘" u2="ù" k="61"/><hkern u1="‘" u2="ø" k="123"/><hkern u1="‘" u2="ö" k="123"/><hkern u1="‘" u2="õ" k="123"/><hkern u1="‘" u2="ô" k="123"/><hkern u1="‘" u2="ó" k="123"/><hkern u1="‘" u2="ò" k="123"/><hkern u1="‘" u2="ë" k="123"/><hkern u1="‘" u2="ê" k="123"/><hkern u1="‘" u2="é" k="123"/><hkern u1="‘" u2="è" k="123"/><hkern u1="‘" u2="ç" k="123"/><hkern u1="‘" u2="æ" k="82"/><hkern u1="‘" u2="å" k="82"/><hkern u1="‘" u2="ä" k="82"/><hkern u1="‘" u2="ã" k="82"/><hkern u1="‘" u2="â" k="82"/><hkern u1="‘" u2="á" k="82"/><hkern u1="‘" u2="à" k="123"/><hkern u1="‘" u2="Ý" k="-20"/><hkern u1="‘" u2="Å" k="143"/><hkern u1="‘" u2="Ä" k="143"/><hkern u1="‘" u2="Ã" k="143"/><hkern u1="‘" u2="Â" k="143"/><hkern u1="‘" u2="Á" k="143"/><hkern u1="‘" u2="À" k="143"/><hkern u1="‘" u2="u" k="61"/><hkern u1="‘" u2="s" k="61"/><hkern u1="‘" u2="r" k="61"/><hkern u1="‘" u2="q" k="123"/><hkern u1="‘" u2="p" k="61"/><hkern u1="‘" u2="o" k="123"/><hkern u1="‘" u2="n" k="61"/><hkern u1="‘" u2="m" k="61"/><hkern u1="‘" u2="g" k="61"/><hkern u1="‘" u2="e" k="123"/><hkern u1="‘" u2="d" k="123"/><hkern u1="‘" u2="c" k="123"/><hkern u1="‘" u2="a" k="82"/><hkern u1="‘" u2="Y" k="-20"/><hkern u1="‘" u2="W" k="-41"/><hkern u1="‘" u2="V" k="-41"/><hkern u1="‘" u2="T" k="-41"/><hkern u1="‘" u2="A" k="143"/><hkern u1="’" u2="Ÿ" k="-20"/><hkern u1="’" u2="œ" k="123"/><hkern u1="’" u2="ü" k="61"/><hkern u1="’" u2="û" k="61"/><hkern u1="’" u2="ú" k="61"/><hkern u1="’" u2="ù" k="61"/><hkern u1="’" u2="ø" k="123"/><hkern u1="’" u2="ö" k="123"/><hkern u1="’" u2="õ" k="123"/><hkern u1="’" u2="ô" k="123"/><hkern u1="’" u2="ó" k="123"/><hkern u1="’" u2="ò" k="123"/><hkern u1="’" u2="ë" k="123"/><hkern u1="’" u2="ê" k="123"/><hkern u1="’" u2="é" k="123"/><hkern u1="’" u2="è" k="123"/><hkern u1="’" u2="ç" k="123"/><hkern u1="’" u2="æ" k="82"/><hkern u1="’" u2="å" k="82"/><hkern u1="’" u2="ä" k="82"/><hkern u1="’" u2="ã" k="82"/><hkern u1="’" u2="â" k="82"/><hkern u1="’" u2="á" k="82"/><hkern u1="’" u2="à" k="123"/><hkern u1="’" u2="Ý" k="-20"/><hkern u1="’" u2="Å" k="143"/><hkern u1="’" u2="Ä" k="143"/><hkern u1="’" u2="Ã" k="143"/><hkern u1="’" u2="Â" k="143"/><hkern u1="’" u2="Á" k="143"/><hkern u1="’" u2="À" k="143"/><hkern u1="’" u2="u" k="61"/><hkern u1="’" u2="s" k="61"/><hkern u1="’" u2="r" k="61"/><hkern u1="’" u2="q" k="123"/><hkern u1="’" u2="p" k="61"/><hkern u1="’" u2="o" k="123"/><hkern u1="’" u2="n" k="61"/><hkern u1="’" u2="m" k="61"/><hkern u1="’" u2="g" k="61"/><hkern u1="’" u2="e" k="123"/><hkern u1="’" u2="d" k="123"/><hkern u1="’" u2="c" k="123"/><hkern u1="’" u2="a" k="82"/><hkern u1="’" u2="Y" k="-20"/><hkern u1="’" u2="W" k="-41"/><hkern u1="’" u2="V" k="-41"/><hkern u1="’" u2="T" k="-41"/><hkern u1="’" u2="A" k="143"/><hkern u1="‚" u2="Ÿ" k="123"/><hkern u1="‚" u2="Œ" k="102"/><hkern u1="‚" u2="Ý" k="123"/><hkern u1="‚" u2="Ü" k="41"/><hkern u1="‚" u2="Û" k="41"/><hkern u1="‚" u2="Ú" k="41"/><hkern u1="‚" u2="Ù" k="41"/><hkern u1="‚" u2="Ø" k="102"/><hkern u1="‚" u2="Ö" k="102"/><hkern u1="‚" u2="Õ" k="102"/><hkern u1="‚" u2="Ô" k="102"/><hkern u1="‚" u2="Ó" k="102"/><hkern u1="‚" u2="Ò" k="102"/><hkern u1="‚" u2="Ç" k="102"/><hkern u1="‚" u2="Y" k="123"/><hkern u1="‚" u2="W" k="123"/><hkern u1="‚" u2="V" k="123"/><hkern u1="‚" u2="U" k="41"/><hkern u1="‚" u2="T" k="143"/><hkern u1="‚" u2="Q" k="102"/><hkern u1="‚" u2="O" k="102"/><hkern u1="‚" u2="G" k="102"/><hkern u1="‚" u2="C" k="102"/><hkern u1="“" u2="Ÿ" k="-20"/><hkern u1="“" u2="œ" k="123"/><hkern u1="“" u2="ü" k="61"/><hkern u1="“" u2="û" k="61"/><hkern u1="“" u2="ú" k="61"/><hkern u1="“" u2="ù" k="61"/><hkern u1="“" u2="ø" k="123"/><hkern u1="“" u2="ö" k="123"/><hkern u1="“" u2="õ" k="123"/><hkern u1="“" u2="ô" k="123"/><hkern u1="“" u2="ó" k="123"/><hkern u1="“" u2="ò" k="123"/><hkern u1="“" u2="ë" k="123"/><hkern u1="“" u2="ê" k="123"/><hkern u1="“" u2="é" k="123"/><hkern u1="“" u2="è" k="123"/><hkern u1="“" u2="ç" k="123"/><hkern u1="“" u2="æ" k="82"/><hkern u1="“" u2="å" k="82"/><hkern u1="“" u2="ä" k="82"/><hkern u1="“" u2="ã" k="82"/><hkern u1="“" u2="â" k="82"/><hkern u1="“" u2="á" k="82"/><hkern u1="“" u2="à" k="123"/><hkern u1="“" u2="Ý" k="-20"/><hkern u1="“" u2="Å" k="143"/><hkern u1="“" u2="Ä" k="143"/><hkern u1="“" u2="Ã" k="143"/><hkern u1="“" u2="Â" k="143"/><hkern u1="“" u2="Á" k="143"/><hkern u1="“" u2="À" k="143"/><hkern u1="“" u2="u" k="61"/><hkern u1="“" u2="s" k="61"/><hkern u1="“" u2="r" k="61"/><hkern u1="“" u2="q" k="123"/><hkern u1="“" u2="p" k="61"/><hkern u1="“" u2="o" k="123"/><hkern u1="“" u2="n" k="61"/><hkern u1="“" u2="m" k="61"/><hkern u1="“" u2="g" k="61"/><hkern u1="“" u2="e" k="123"/><hkern u1="“" u2="d" k="123"/><hkern u1="“" u2="c" k="123"/><hkern u1="“" u2="a" k="82"/><hkern u1="“" u2="Y" k="-20"/><hkern u1="“" u2="W" k="-41"/><hkern u1="“" u2="V" k="-41"/><hkern u1="“" u2="T" k="-41"/><hkern u1="“" u2="A" k="143"/><hkern u1="„" u2="Ÿ" k="123"/><hkern u1="„" u2="Œ" k="102"/><hkern u1="„" u2="Ý" k="123"/><hkern u1="„" u2="Ü" k="41"/><hkern u1="„" u2="Û" k="41"/><hkern u1="„" u2="Ú" k="41"/><hkern u1="„" u2="Ù" k="41"/><hkern u1="„" u2="Ø" k="102"/><hkern u1="„" u2="Ö" k="102"/><hkern u1="„" u2="Õ" k="102"/><hkern u1="„" u2="Ô" k="102"/><hkern u1="„" u2="Ó" k="102"/><hkern u1="„" u2="Ò" k="102"/><hkern u1="„" u2="Ç" k="102"/><hkern u1="„" u2="Y" k="123"/><hkern u1="„" u2="W" k="123"/><hkern u1="„" u2="V" k="123"/><hkern u1="„" u2="U" k="41"/><hkern u1="„" u2="T" k="143"/><hkern u1="„" u2="Q" k="102"/><hkern u1="„" u2="O" k="102"/><hkern u1="„" u2="G" k="102"/><hkern u1="„" u2="C" k="102"/></font></defs></svg> \ No newline at end of file diff --git a/lib/web/fonts/opensans/semibold/opensans-600.ttf b/lib/web/fonts/opensans/semibold/opensans-600.ttf deleted file mode 100644 index b3290843a7a3e..0000000000000 Binary files a/lib/web/fonts/opensans/semibold/opensans-600.ttf and /dev/null differ diff --git a/lib/web/mage/apply/scripts.js b/lib/web/mage/apply/scripts.js index f35e9a2140e67..bf211c38adba5 100644 --- a/lib/web/mage/apply/scripts.js +++ b/lib/web/mage/apply/scripts.js @@ -14,7 +14,7 @@ define([ virtuals = []; /** - * Adds components to the virtula list. + * Adds components to the virtual list. * * @param {Object} components */ diff --git a/lib/web/mage/calendar.js b/lib/web/mage/calendar.js index 51ee9b3a8891a..ac154b333801d 100644 --- a/lib/web/mage/calendar.js +++ b/lib/web/mage/calendar.js @@ -236,12 +236,14 @@ firstDay = parseInt(this._get(inst, 'firstDay'), 10); firstDay = isNaN(firstDay) ? 0 : firstDay; - for (row; row < numMonths[0]; row++) { + for (row = 0; row < numMonths[0]; row++) { this.maxRows = 4; - for (col; col < numMonths[1]; col++) { + for (col = 0; col < numMonths[1]; col++) { selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); + calender = ''; + if (isMultiMonth) { calender += '<div class="ui-datepicker-group'; @@ -271,7 +273,7 @@ thead = showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : ''; - for (dow; dow < 7; dow++) { // days of the week + for (dow = 0; dow < 7; dow++) { // days of the week day = (dow + firstDay) % 7; thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' + @@ -289,7 +291,7 @@ this.maxRows = numRows; printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); - for (dRow; dRow < numRows; dRow++) { // create date picker rows + for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows calender += '<tr>'; tbody = !showWeek ? '' : '<td class="ui-datepicker-week-col">' + this._get(inst, 'calculateWeek')(printDate) + '</td>'; diff --git a/lib/web/mage/trim-input.js b/lib/web/mage/trim-input.js new file mode 100644 index 0000000000000..678192dcf61ac --- /dev/null +++ b/lib/web/mage/trim-input.js @@ -0,0 +1,60 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'jquery' +], function ($) { + 'use strict'; + + $.widget('mage.trimInput', { + options: { + cache: {} + }, + + /** + * Widget initialization + * @private + */ + _create: function () { + this.options.cache.input = $(this.element); + this._bind(); + }, + + /** + * Event binding, will monitor change, keyup and paste events. + * @private + */ + _bind: function () { + if (this.options.cache.input.length) { + this._on(this.options.cache.input, { + 'change': this._trimInput, + 'keyup': this._trimInput, + 'paste': this._trimInput + }); + } + }, + + /** + * Trim value + * @private + */ + _trimInput: function () { + var input = this._getInputValue().trim(); + + this.options.cache.input.val(input); + }, + + /** + * Get input value + * @returns {*} + * @private + */ + _getInputValue: function () { + return this.options.cache.input.val(); + } + }); + + return $.mage.trimInput; +}); diff --git a/lib/web/modernizr/modernizr.js b/lib/web/modernizr/modernizr.js index 9b4f68aaaaaa9..0833cfb105cee 100644 --- a/lib/web/modernizr/modernizr.js +++ b/lib/web/modernizr/modernizr.js @@ -910,7 +910,7 @@ window.Modernizr = (function( window, document, undefined ) { bool = inputElem.checkValidity && inputElem.checkValidity() === false; } else { - // If the upgraded input compontent rejects the :) text, we got a winner + // If the upgraded input component rejects the :) text, we got a winner bool = inputElem.value != smile; } } diff --git a/setup/src/Magento/Setup/Fixtures/FixtureModel.php b/setup/src/Magento/Setup/Fixtures/FixtureModel.php index 104c9cb343216..99237e48748fb 100644 --- a/setup/src/Magento/Setup/Fixtures/FixtureModel.php +++ b/setup/src/Magento/Setup/Fixtures/FixtureModel.php @@ -105,7 +105,7 @@ public function reindex(OutputInterface $output) */ public function loadFixtures() { - $files = glob(__DIR__ . DIRECTORY_SEPARATOR . self::FIXTURE_PATTERN); + $files = glob(__DIR__ . DIRECTORY_SEPARATOR . self::FIXTURE_PATTERN, GLOB_NOSORT); foreach ($files as $file) { $file = basename($file, '.php'); diff --git a/setup/src/Magento/Setup/Fixtures/OrdersFixture.php b/setup/src/Magento/Setup/Fixtures/OrdersFixture.php index 1acad6dbc1787..9fbec3b3741b2 100644 --- a/setup/src/Magento/Setup/Fixtures/OrdersFixture.php +++ b/setup/src/Magento/Setup/Fixtures/OrdersFixture.php @@ -14,7 +14,7 @@ * Optionally generates inactive quotes for generated orders. * * Support the following format: - * <!-- Is is nescessary to enable quotes for orders --> + * <!-- It is necessary to enable quotes for orders --> * <order_quotes_enable>{bool}</order_quotes_enable> * * <!-- Min number of simple products per each order --> diff --git a/setup/src/Magento/Setup/Fixtures/StoresFixture.php b/setup/src/Magento/Setup/Fixtures/StoresFixture.php index fb8679b5c879a..17b83e627ab9c 100644 --- a/setup/src/Magento/Setup/Fixtures/StoresFixture.php +++ b/setup/src/Magento/Setup/Fixtures/StoresFixture.php @@ -211,9 +211,6 @@ public function execute() $this->generateWebsites(); $this->generateStoreGroups(); $this->generateStoreViews(); - - //clean cache - $this->storeManager->reinitStores(); } /** @@ -305,7 +302,6 @@ private function generateStoreViews() 'code' => $storeCode ] )->save(); - $this->eventManager->dispatch('store_add', ['store' => $store]); $this->saveStoreLocale($store->getId(), $localesList[$existedStoreViewsCount % $localesListCount]); } diff --git a/setup/src/Magento/Setup/Module/Dependency/Circular.php b/setup/src/Magento/Setup/Module/Dependency/Circular.php index 8f5bd8716f650..a10d2752fa410 100644 --- a/setup/src/Magento/Setup/Module/Dependency/Circular.php +++ b/setup/src/Magento/Setup/Module/Dependency/Circular.php @@ -118,7 +118,7 @@ protected function buildCircular($modules) return; } $this->circularDependencies[$path] = $modules; - array_push($modules, array_shift($modules)); + $modules[] = array_shift($modules); $this->buildCircular($modules); } @@ -133,7 +133,7 @@ protected function divideByModules($circularDependencies) $dependenciesByModule = []; foreach ($circularDependencies as $circularDependency) { $module = $circularDependency[0]; - array_push($circularDependency, $module); + $circularDependency[] = $module; $dependenciesByModule[$module][] = $circularDependency; } diff --git a/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlInterceptorScanner.php b/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlInterceptorScanner.php index e88ca9197096a..75c6e1144e8d2 100644 --- a/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlInterceptorScanner.php +++ b/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlInterceptorScanner.php @@ -42,9 +42,9 @@ protected function _collectEntitiesFromString($content) $attributes = $entityNode->attributes; $type = $attributes->getNamedItem('type'); if ($type !== null) { - array_push($output, $type->nodeValue); + $output[] = $type->nodeValue; } else { - array_push($output, $attributes->getNamedItem('name')->nodeValue); + $output[] = $attributes->getNamedItem('name')->nodeValue; } } return $output; @@ -80,7 +80,7 @@ protected function _filterEntities(array $output) $this->_handleControllerClassName($entityName); } if (class_exists($entityName) || interface_exists($entityName)) { - array_push($filteredEntities, $entityName . '\\Interceptor'); + $filteredEntities[] = $entityName . '\\Interceptor'; } } return $filteredEntities; diff --git a/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlScanner.php b/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlScanner.php index 37388f563e75b..a606c266d3827 100644 --- a/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlScanner.php +++ b/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlScanner.php @@ -104,7 +104,7 @@ protected function _filterEntities(array $output) } if (false === $isClassExists) { if (class_exists($entityName) || interface_exists($entityName)) { - array_push($filteredEntities, $className); + $filteredEntities[] = $className; } else { $this->_log->add( \Magento\Setup\Module\Di\Compiler\Log\Log::CONFIGURATION_ERROR, diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/StoresFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/StoresFixtureTest.php index 1bedfd4b6b975..9fc74066e618c 100644 --- a/setup/src/Magento/Setup/Test/Unit/Fixtures/StoresFixtureTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/StoresFixtureTest.php @@ -75,7 +75,6 @@ public function testExecute() 'getDefaultStoreView', 'getStore', 'getStores', - 'reinitStores' ] )->getMock(); @@ -250,10 +249,6 @@ public function testExecute() ) ->willReturn($storeGroupMock); - $this->storeManagerMock->expects($this->once()) - ->method('reinitStores') - ->willReturn('void'); - $this->storeManagerMock->expects($this->once()) ->method('getGroups') ->willReturn([$storeGroupMock]);