/**
  * Loads the whole menu tree.
  */
 public function expandAll($tree)
 {
     foreach ($tree as $key => $element) {
         if ($element->hasChildren && null !== $element->link && !$element->link instanceof InaccessibleMenuLink) {
             $menu_tree = \Drupal::menuTree();
             $parameters = new MenuTreeParameters();
             $parameters->setRoot($element->link->getPluginId())->excludeRoot()->setMaxDepth(1)->onlyEnabledLinks();
             $subtree = $menu_tree->load(NULL, $parameters);
             if ($subtree) {
                 $tree[$key]->subtree = $this->expandAll($subtree);
             }
         }
     }
     return $tree;
 }
 /**
  * Responds to GET requests.
  *
  * Returns a menu tree for the specified menu name.
  *
  * @param int $menu_name
  *   The machine name of the Drupal menu.
  *
  * @return \Drupal\rest\ResourceResponse
  *   The response containing the menu tree.
  *
  * @throws \Symfony\Component\HttpKernel\Exception\HttpException
  */
 public function get($menu_name = NULL)
 {
     if ($menu_name) {
         // Get menu tree resource config, set at /admin/config/services/menutree.
         $config = \Drupal::config('menutree_resource.services_settings');
         $services_menus = $config->get('services_menus');
         // Only allow a response if the menu is in config
         if (in_array($menu_name, array_filter(array_values($services_menus)))) {
             $menu_tree = \Drupal::menuTree();
             $parameters = new MenuTreeParameters();
             $parameters->onlyEnabledLinks();
             $tree = $menu_tree->load($menu_name, $parameters);
             if (!empty($tree)) {
                 $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'));
                 $tree = $menu_tree->transform($tree, $manipulators);
                 $build = $menu_tree->build($tree);
                 // Clean the menu tree so it's ready for serialisation in a resource response.
                 $items = $this->clean_tree($build['#items']);
                 return new ResourceResponse($items);
             }
             throw new NotFoundHttpException(t('Menu with name @menu_name was not found', array('@menu_name' => $menu_name)));
         }
         throw new NotFoundHttpException(t('Menu tree @menu_name not allowed.', array('@menu_name' => $menu_name)));
     }
     throw new HttpException(t('No menu name was provided'));
 }
예제 #3
0
 /**
  * {@inheritdoc}
  */
 public function getCurrentRouteMenuTreeParameters($menu_name)
 {
     $active_trail = $this->menuActiveTrail->getActiveTrailIds($menu_name);
     $parameters = new MenuTreeParameters();
     $parameters->setActiveTrail($active_trail)->addExpandedParents($active_trail)->addExpandedParents($this->treeStorage->getExpanded($menu_name, $active_trail));
     return $parameters;
 }
 /**
  * @return array
  *    Array containing Devel Menu links
  */
 protected function develMenuLinks()
 {
     $parameters = new MenuTreeParameters();
     $parameters->setMaxDepth(1)->onlyEnabledLinks();
     $tree = $this->menuLinkTree->load('devel', $parameters);
     $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'));
     $tree = $this->menuLinkTree->transform($tree, $manipulators);
     $links = array();
     foreach ($tree as $item) {
         if ($item->access->isAllowed()) {
             $links[] = array('title' => $item->link->getTitle(), 'description' => $item->link->getDescription(), 'url' => $item->link->getUrlObject()->toString());
         }
     }
     return $links;
 }
 /**
  * {@inheritdoc}
  */
 public function getParentSelectOptions($id = '', array $menus = NULL)
 {
     if (!isset($menus)) {
         $menus = $this->getMenuOptions();
     }
     $options = array();
     $depth_limit = $this->getParentDepthLimit($id);
     foreach ($menus as $menu_name => $menu_title) {
         $options[$menu_name . ':'] = '<' . $menu_title . '>';
         $parameters = new MenuTreeParameters();
         $parameters->setMaxDepth($depth_limit);
         $tree = $this->menuLinkTree->load($menu_name, $parameters);
         $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'));
         $tree = $this->menuLinkTree->transform($tree, $manipulators);
         $this->parentSelectOptionsTreeWalk($tree, $menu_name, '--', $options, $id, $depth_limit);
     }
     return $options;
 }
예제 #6
0
 /**
  * Tests the loadTreeData method.
  */
 public function testLoadTree()
 {
     $this->addMenuLink('test1', '');
     $this->addMenuLink('test2', 'test1');
     $this->addMenuLink('test3', 'test2');
     $this->addMenuLink('test4');
     $this->addMenuLink('test5', 'test4');
     $data = $this->treeStorage->loadTreeData('tools', new MenuTreeParameters());
     $tree = $data['tree'];
     $this->assertEqual(count($tree['test1']['subtree']), 1);
     $this->assertEqual(count($tree['test1']['subtree']['test2']['subtree']), 1);
     $this->assertEqual(count($tree['test1']['subtree']['test2']['subtree']['test3']['subtree']), 0);
     $this->assertEqual(count($tree['test4']['subtree']), 1);
     $this->assertEqual(count($tree['test4']['subtree']['test5']['subtree']), 0);
     $parameters = new MenuTreeParameters();
     $parameters->setActiveTrail(array('test4', 'test5'));
     $data = $this->treeStorage->loadTreeData('tools', $parameters);
     $tree = $data['tree'];
     $this->assertEqual(count($tree['test1']['subtree']), 1);
     $this->assertFalse($tree['test1']['in_active_trail']);
     $this->assertEqual(count($tree['test1']['subtree']['test2']['subtree']), 1);
     $this->assertFalse($tree['test1']['subtree']['test2']['in_active_trail']);
     $this->assertEqual(count($tree['test1']['subtree']['test2']['subtree']['test3']['subtree']), 0);
     $this->assertFalse($tree['test1']['subtree']['test2']['subtree']['test3']['in_active_trail']);
     $this->assertEqual(count($tree['test4']['subtree']), 1);
     $this->assertTrue($tree['test4']['in_active_trail']);
     $this->assertEqual(count($tree['test4']['subtree']['test5']['subtree']), 0);
     $this->assertTrue($tree['test4']['subtree']['test5']['in_active_trail']);
     // Add some conditions to ensure that conditions work as expected.
     $parameters = new MenuTreeParameters();
     $parameters->addCondition('parent', 'test1');
     $data = $this->treeStorage->loadTreeData('tools', $parameters);
     $this->assertEqual(count($data['tree']), 1);
     $this->assertEqual($data['tree']['test2']['definition']['id'], 'test2');
     $this->assertEqual($data['tree']['test2']['subtree'], []);
     // Test for only enabled links.
     $link = $this->treeStorage->load('test3');
     $link['enabled'] = FALSE;
     $this->treeStorage->save($link);
     $link = $this->treeStorage->load('test4');
     $link['enabled'] = FALSE;
     $this->treeStorage->save($link);
     $link = $this->treeStorage->load('test5');
     $link['enabled'] = FALSE;
     $this->treeStorage->save($link);
     $parameters = new MenuTreeParameters();
     $parameters->onlyEnabledLinks();
     $data = $this->treeStorage->loadTreeData('tools', $parameters);
     $this->assertEqual(count($data['tree']), 1);
     $this->assertEqual($data['tree']['test1']['definition']['id'], 'test1');
     $this->assertEqual(count($data['tree']['test1']['subtree']), 1);
     $this->assertEqual($data['tree']['test1']['subtree']['test2']['definition']['id'], 'test2');
     $this->assertEqual($data['tree']['test1']['subtree']['test2']['subtree'], []);
 }
예제 #7
0
 /**
  * {@inheritdoc}
  */
 public function loadAllChildren($id, $max_relative_depth = NULL)
 {
     $parameters = new MenuTreeParameters();
     $parameters->setRoot($id)->excludeRoot()->setMaxDepth($max_relative_depth)->onlyEnabledLinks();
     $links = $this->loadLinks(NULL, $parameters);
     foreach ($links as $id => $link) {
         $links[$id] = $this->prepareLink($link);
     }
     return $links;
 }
 /**
  * Tests creating links with an expected tree structure.
  */
 public function testCreateLinksInMenu()
 {
     // This creates a tree with the following structure:
     // - 1
     // - 2
     //   - 3
     //     - 4
     // - 5
     //   - 7
     // - 6
     // - 8
     // With link 6 being the only external link.
     $links = array(1 => MenuLinkMock::create(array('id' => 'test.example1', 'route_name' => 'example1', 'title' => 'foo', 'parent' => '')), 2 => MenuLinkMock::create(array('id' => 'test.example2', 'route_name' => 'example2', 'title' => 'bar', 'parent' => 'test.example1', 'route_parameters' => array('foo' => 'bar'))), 3 => MenuLinkMock::create(array('id' => 'test.example3', 'route_name' => 'example3', 'title' => 'baz', 'parent' => 'test.example2', 'route_parameters' => array('baz' => 'qux'))), 4 => MenuLinkMock::create(array('id' => 'test.example4', 'route_name' => 'example4', 'title' => 'qux', 'parent' => 'test.example3')), 5 => MenuLinkMock::create(array('id' => 'test.example5', 'route_name' => 'example5', 'title' => 'foofoo', 'parent' => '')), 6 => MenuLinkMock::create(array('id' => 'test.example6', 'route_name' => '', 'url' => 'https://drupal.org/', 'title' => 'barbar', 'parent' => '')), 7 => MenuLinkMock::create(array('id' => 'test.example7', 'route_name' => 'example7', 'title' => 'bazbaz', 'parent' => '')), 8 => MenuLinkMock::create(array('id' => 'test.example8', 'route_name' => 'example8', 'title' => 'quxqux', 'parent' => '')));
     foreach ($links as $instance) {
         $this->menuLinkManager->addDefinition($instance->getPluginId(), $instance->getPluginDefinition());
     }
     $parameters = new MenuTreeParameters();
     $tree = $this->linkTree->load('mock', $parameters);
     $count = function (array $tree) {
         $sum = function ($carry, MenuLinkTreeElement $item) {
             return $carry + $item->count();
         };
         return array_reduce($tree, $sum);
     };
     $this->assertEqual($count($tree), 8);
     $parameters = new MenuTreeParameters();
     $parameters->setRoot('test.example2');
     $tree = $this->linkTree->load($instance->getMenuName(), $parameters);
     $top_link = reset($tree);
     $this->assertEqual(count($top_link->subtree), 1);
     $child = reset($top_link->subtree);
     $this->assertEqual($child->link->getPluginId(), $links[3]->getPluginId());
     $height = $this->linkTree->getSubtreeHeight('test.example2');
     $this->assertEqual($height, 3);
 }
예제 #9
0
 /**
  * Tests the regression in https://www.drupal.org/node/2532490.
  */
 public function testDefaultMenuTabRegression()
 {
     $this->container->get('module_installer')->install(['menu_ui', 'menu_link_content', 'toolbar', 'system']);
     $admin_user = $this->drupalCreateUser(['administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view all revisions', 'administer permissions', 'administer menu', 'link to any page', 'access toolbar']);
     $this->drupalLogin($admin_user);
     $edit = ['title[0][value]' => 'Menu title', 'link[0][uri]' => '/admin/foo', 'menu_parent' => 'admin:system.admin'];
     $this->drupalPostForm('admin/structure/menu/manage/admin/add', $edit, t('Save'));
     $menu_items = \Drupal::entityManager()->getStorage('menu_link_content')->getQuery()->sort('id', 'DESC')->pager(1)->execute();
     $menu_item = end($menu_items);
     /** @var \Drupal\menu_link_content\MenuLinkContentInterface $menu_link_content */
     $menu_link_content = MenuLinkContent::load($menu_item);
     $edit = [];
     $edit['label'] = $this->randomMachineName(16);
     $view_id = $edit['id'] = strtolower($this->randomMachineName(16));
     $edit['description'] = $this->randomMachineName(16);
     $edit['page[create]'] = TRUE;
     $edit['page[path]'] = 'admin/foo';
     $this->drupalPostForm('admin/structure/views/add', $edit, t('Save and edit'));
     $parameters = new MenuTreeParameters();
     $parameters->addCondition('id', $menu_link_content->getPluginId());
     $result = \Drupal::menuTree()->load('admin', $parameters);
     $plugin_definition = end($result)->link->getPluginDefinition();
     $this->assertEqual('view.' . $view_id . '.page_1', $plugin_definition['route_name']);
     $this->clickLink(t('No menu'));
     $this->drupalPostForm(NULL, ['menu[type]' => 'default tab', 'menu[title]' => 'Menu title'], t('Apply'));
     $this->assertText('Default tab options');
     $this->drupalPostForm(NULL, ['tab_options[type]' => 'normal', 'tab_options[title]' => 'Parent title'], t('Apply'));
     $this->drupalPostForm(NULL, [], t('Save'));
     // Assert that saving the view will not cause an exception.
     $this->assertResponse(200);
 }
예제 #10
0
 /**
  * Tests excludeRoot().
  *
  * @covers ::excludeRoot
  */
 public function testExcludeRoot()
 {
     $parameters = new MenuTreeParameters();
     $parameters->excludeRoot();
     $this->assertEquals(1, $parameters->minDepth);
 }
예제 #11
0
 /**
  * Provide the administration overview page.
  *
  * @param string $link_id
  *   The ID of the administrative path link for which to display child links.
  *
  * @return array
  *   A renderable array of the administration overview page.
  */
 public function overview($link_id)
 {
     // Check for status report errors.
     if ($this->systemManager->checkRequirements() && $this->currentUser()->hasPermission('administer site configuration')) {
         drupal_set_message($this->t('One or more problems were detected with your Drupal installation. Check the <a href="@status">status report</a> for more information.', array('@status' => $this->url('system.status'))), 'error');
     }
     // Load all menu links below it.
     $parameters = new MenuTreeParameters();
     $parameters->setRoot($link_id)->excludeRoot()->setTopLevelOnly()->onlyEnabledLinks();
     $tree = $this->menuLinkTree->load(NULL, $parameters);
     $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'));
     $tree = $this->menuLinkTree->transform($tree, $manipulators);
     $tree_access_cacheability = new CacheableMetadata();
     $blocks = array();
     foreach ($tree as $key => $element) {
         $tree_access_cacheability = $tree_access_cacheability->merge(CacheableMetadata::createFromObject($element->access));
         // Only render accessible links.
         if (!$element->access->isAllowed()) {
             continue;
         }
         $link = $element->link;
         $block['title'] = $link->getTitle();
         $block['description'] = $link->getDescription();
         $block['content'] = array('#theme' => 'admin_block_content', '#content' => $this->systemManager->getAdminBlock($link));
         if (!empty($block['content']['#content'])) {
             $blocks[$key] = $block;
         }
     }
     if ($blocks) {
         ksort($blocks);
         $build = ['#theme' => 'admin_page', '#blocks' => $blocks];
         $tree_access_cacheability->applyTo($build);
         return $build;
     } else {
         $build = ['#markup' => $this->t('You do not have any administrative items.')];
         $tree_access_cacheability->applyTo($build);
         return $build;
     }
 }
예제 #12
0
 /**
  * Generates menu links in a tree structure.
  */
 protected function generateLinks($num_links, $menus, $title_length, $link_types, $max_depth, $max_width)
 {
     $links = array();
     $menus = array_keys(array_filter($menus));
     $link_types = array_keys(array_filter($link_types));
     $nids = array();
     for ($i = 1; $i <= $num_links; $i++) {
         // Pick a random menu.
         $menu_name = $menus[array_rand($menus)];
         // Build up our link.
         $link_title = $this->getRandom()->word(mt_rand(2, max(2, $title_length)));
         $link = $this->menuLinkContentStorage->create(array('menu_name' => $menu_name, 'weight' => mt_rand(-50, 50), 'title' => $link_title, 'bundle' => 'menu_link_content', 'description' => $this->t('Description of @title.', array('@title' => $link_title))));
         $link->link->options = array('devel' => TRUE);
         // For the first $max_width items, make first level links.
         if ($i <= $max_width) {
             $depth = 0;
         } else {
             // Otherwise, get a random parent menu depth.
             $depth = mt_rand(1, max(1, $max_depth - 1));
         }
         // Get a random parent link from the proper depth.
         do {
             $parameters = new MenuTreeParameters();
             $parameters->setMinDepth($depth);
             $parameters->setMaxDepth($depth);
             $tree = $this->menuLinkTree->load($menu_name, $parameters);
             if ($tree) {
                 $link->parent = array_rand($tree);
             }
             $depth--;
         } while (!$link->parent && $depth > 0);
         $link_type = array_rand($link_types);
         switch ($link_types[$link_type]) {
             case 'node':
                 // Grab a random node ID.
                 $select = db_select('node_field_data', 'n')->fields('n', array('nid', 'title'))->condition('n.status', 1)->range(0, 1)->orderRandom();
                 // Don't put a node into the menu twice.
                 if (!empty($nids[$menu_name])) {
                     $select->condition('n.nid', $nids[$menu_name], 'NOT IN');
                 }
                 $node = $select->execute()->fetchAssoc();
                 if (isset($node['nid'])) {
                     $nids[$menu_name][] = $node['nid'];
                     $link->link->uri = 'entity:node/' . $node['nid'];
                     $link->title = $node['title'];
                     break;
                 }
             case 'external':
                 $link->link->uri = 'http://www.example.com/';
                 break;
             case 'front':
                 $link->link->uri = 'internal:/<front>';
                 break;
             default:
                 $link->devel_link_type = $link_type;
                 break;
         }
         $link->save();
         $links[$link->id()] = $link->link_title;
     }
     return $links;
 }
예제 #13
0
 /**
  * Provide a single block on the administration overview page.
  *
  * @param \Drupal\Core\Menu\MenuLinkInterface $instance
  *   The menu item to be displayed.
  *
  * @return array
  *   An array of menu items, as expected by admin-block-content.html.twig.
  */
 public function getAdminBlock(MenuLinkInterface $instance)
 {
     $content = array();
     // Only find the children of this link.
     $link_id = $instance->getPluginId();
     $parameters = new MenuTreeParameters();
     $parameters->setRoot($link_id)->excludeRoot()->setTopLevelOnly()->onlyEnabledLinks();
     $tree = $this->menuTree->load(NULL, $parameters);
     $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'));
     $tree = $this->menuTree->transform($tree, $manipulators);
     foreach ($tree as $key => $element) {
         // Only render accessible links.
         if (!$element->access->isAllowed()) {
             // @todo Bubble cacheability metadata of both accessible and
             //   inaccessible links. Currently made impossible by the way admin
             //   blocks are rendered.
             continue;
         }
         /** @var $link \Drupal\Core\Menu\MenuLinkInterface */
         $link = $element->link;
         $content[$key]['title'] = $link->getTitle();
         $content[$key]['options'] = $link->getOptions();
         $content[$key]['description'] = $link->getDescription();
         $content[$key]['url'] = $link->getUrlObject();
     }
     ksort($content);
     return $content;
 }
예제 #14
0
 /**
  * Returns all top level menu links.
  *
  * @return \Drupal\Core\Menu\MenuLinkInterface[]
  */
 protected function getTopLevelMenuLinks()
 {
     $menu_tree = \Drupal::menuTree();
     // The system.admin link is normally the parent of all top-level admin links.
     $parameters = new MenuTreeParameters();
     $parameters->setRoot('system.admin')->excludeRoot()->setTopLevelOnly()->excludeHiddenLinks();
     $tree = $menu_tree->load(NULL, $parameters);
     $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:flatten'));
     $tree = $menu_tree->transform($tree, $manipulators);
     // Transform the tree to a list of menu links.
     $menu_links = array();
     foreach ($tree as $element) {
         $menu_links[] = $element->link;
     }
     return $menu_links;
 }
예제 #15
0
 /**
  * {@inheritdoc}
  */
 public function getCurrentRouteMenuTreeParameters($menu_name)
 {
     $route_parameters = $this->routeMatch->getRawParameters()->all();
     ksort($route_parameters);
     $cid = 'current-route-parameters:' . $menu_name . ':route:' . $this->routeMatch->getRouteName() . ':route_parameters:' . serialize($route_parameters);
     if (!isset($this->cachedCurrentRouteParameters[$menu_name])) {
         $cache = $this->cache->get($cid);
         if ($cache && $cache->data) {
             $parameters = $cache->data;
         } else {
             $active_trail = $this->menuActiveTrail->getActiveTrailIds($menu_name);
             $parameters = new MenuTreeParameters();
             $parameters->setActiveTrail($active_trail)->addExpandedParents($active_trail)->addExpandedParents($this->treeStorage->getExpanded($menu_name, $active_trail));
             $this->cache->set($cid, $parameters, CacheBackendInterface::CACHE_PERMANENT, array('menu' => $menu_name));
         }
         $this->cachedCurrentRouteParameters[$menu_name] = $parameters;
     }
     return $this->cachedCurrentRouteParameters[$menu_name];
 }
예제 #16
0
 /**
  * Provide a single block on the administration overview page.
  *
  * @param \Drupal\Core\Menu\MenuLinkInterface $instance
  *   The menu item to be displayed.
  *
  * @return array
  *   An array of menu items, as expected by theme_admin_block_content().
  */
 public function getAdminBlock(MenuLinkInterface $instance)
 {
     $content = array();
     // Only find the children of this link.
     $link_id = $instance->getPluginId();
     $parameters = new MenuTreeParameters();
     $parameters->setRoot($link_id)->excludeRoot()->setTopLevelOnly()->excludeHiddenLinks();
     $tree = $this->menuTree->load(NULL, $parameters);
     $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'));
     $tree = $this->menuTree->transform($tree, $manipulators);
     foreach ($tree as $key => $element) {
         /** @var $link \Drupal\Core\Menu\MenuLinkInterface */
         $link = $element->link;
         $content[$key]['title'] = $link->getTitle();
         $content[$key]['options'] = $link->getOptions();
         $content[$key]['description'] = $link->getDescription();
         $content[$key]['url'] = $link->getUrlObject();
     }
     ksort($content);
     return $content;
 }
예제 #17
0
 /**
  * Tests the loadTreeData method.
  */
 public function testLoadTree()
 {
     $this->addMenuLink('test1', '');
     $this->addMenuLink('test2', 'test1');
     $this->addMenuLink('test3', 'test2');
     $this->addMenuLink('test4');
     $this->addMenuLink('test5', 'test4');
     $data = $this->treeStorage->loadTreeData('tools', new MenuTreeParameters());
     $tree = $data['tree'];
     $this->assertEqual(count($tree['test1']['subtree']), 1);
     $this->assertEqual(count($tree['test1']['subtree']['test2']['subtree']), 1);
     $this->assertEqual(count($tree['test1']['subtree']['test2']['subtree']['test3']['subtree']), 0);
     $this->assertEqual(count($tree['test4']['subtree']), 1);
     $this->assertEqual(count($tree['test4']['subtree']['test5']['subtree']), 0);
     $parameters = new MenuTreeParameters();
     $parameters->setActiveTrail(array('test4', 'test5'));
     $data = $this->treeStorage->loadTreeData('tools', $parameters);
     $tree = $data['tree'];
     $this->assertEqual(count($tree['test1']['subtree']), 1);
     $this->assertFalse($tree['test1']['in_active_trail']);
     $this->assertEqual(count($tree['test1']['subtree']['test2']['subtree']), 1);
     $this->assertFalse($tree['test1']['subtree']['test2']['in_active_trail']);
     $this->assertEqual(count($tree['test1']['subtree']['test2']['subtree']['test3']['subtree']), 0);
     $this->assertFalse($tree['test1']['subtree']['test2']['subtree']['test3']['in_active_trail']);
     $this->assertEqual(count($tree['test4']['subtree']), 1);
     $this->assertTrue($tree['test4']['in_active_trail']);
     $this->assertEqual(count($tree['test4']['subtree']['test5']['subtree']), 0);
     $this->assertTrue($tree['test4']['subtree']['test5']['in_active_trail']);
 }