d发个发成功96666699🐶 �����ѩ�����һ����dddf2qevf2fv69666 ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!PKi5] Gj knp-menu/CODE_OF_CONDUCT.mdnu[# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the project or its community in public spaces. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org ## Contact If you have any questions or feedback, [please ping us](https://twitter.com/KNPLabs) ! PKi5]~D9] ] knp-menu/README.markdownnu[KnpMenu ======= The KnpMenu library provides object oriented menus for PHP 7. It is used by the [KnpMenuBundle](https://github.com/KnpLabs/KnpMenuBundle) for Symfony but can now be used stand-alone. [![Build Status](https://secure.travis-ci.org/KnpLabs/KnpMenu.svg)](http://travis-ci.org/KnpLabs/KnpMenu) [![Latest Stable Version](https://poser.pugx.org/knplabs/knp-menu/v/stable.svg)](https://packagist.org/packages/knplabs/knp-menu) [![Latest Unstable Version](https://poser.pugx.org/knplabs/knp-menu/v/unstable.svg)](https://packagist.org/packages/knplabs/knp-menu) [![Gitter chat](https://badges.gitter.im/KnpLabs/KnpMenu.svg)](https://gitter.im/KnpLabs/KnpMenu) ## Installation KnpMenu uses Composer, please checkout the [composer website](http://getcomposer.org) for more information. The simple following command will install `knp-menu` into your project. It also add a new entry in your `composer.json` and update the `composer.lock` as well. ```bash $ composer require knplabs/knp-menu ``` > KnpMenu follows the PSR-4 convention names for its classes, which means you can easily integrate `knp-menu` classes loading in your own autoloader. ## Getting Started ```php createItem('My menu'); $menu->addChild('Home', ['uri' => '/']); $menu->addChild('Comments', ['uri' => '#comments']); $menu->addChild('Symfony', ['uri' => 'http://symfony.com/']); $menu->addChild('Happy Awesome Developers'); $renderer = new ListRenderer(new \Knp\Menu\Matcher\Matcher()); echo $renderer->render($menu); ``` The above menu would render the following HTML: ```html ``` This way you can finally avoid writing an ugly template to show the selected item, the first and last items, submenus, ... > The bulk of the documentation can be found in the `doc` directory. ## What now? Follow the tutorial in [`doc/01-Basic-Menus.md`][0] and [`doc/02-Twig-Integration.md`][1] to discover how KnpMenu will rock your world! Find all available documentation at [`doc/`][2]. ## Maintainers This library is maintained by the following people (alphabetically sorted) : - @derrabus - @garak - @stof ## Credits This bundle was originally ported from [ioMenuPlugin](http://github.com/weaverryan/ioMenuPlugin), a menu plugin for symfony1. It has since been developed by [KnpLabs](http://www.knplabs.com) and the [Symfony community](https://github.com/KnpLabs/KnpMenu/graphs/contributors). [0]: doc/01-Basic-Menus.md [1]: doc/02-Twig-Integration.md [2]: doc/ PKi5]jdknp-menu/CHANGELOG.mdnu[## 3.1 (2019-12-01) * Allowed Symfony 5 components * Removed support for unsupported Symfony versions (4.0 and 4.1) * Allowed Twig 3 ## 3.0 (2019-09-02) * Raised PHP requirements * [BC break] Enforced strong types on all interfaces and classes * [BC break] Removed deprecated features. Specifically, MenuFactory and MenuItem are not accepting a `null` name anymore ## 2.4 (2019-07-29) * Fixed Twig deprecations * Switched to namespaced Twig * Fixed sprintf use ## 2.3 (2017-11-18) * Deprecated the Silex 1 KnpMenuServiceProvider. Use the `knplabs/knp-menu-silex` package instead. * Fixed RouteVoter to also match on non-string request arguments like integers as long as both string representations are identical. * Add Symfony 4 support ## 2.2 (2016-09-22) * Added a new function to twig: `knp_menu_get_current_item` ## 2.1.1 (2016-01-08) * Made compatible with Symfony 3 ## 2.1.0 (2015-09-20) * Added a new function to twig: `knp_menu_get_breadcrumbs_array` * Added a new filter to twig: `knp_menu_as_string` * Added 2 new tests to twig: `knp_menu_current`, `knp_menu_ancestor` * Made the templates compatible with Twig 2 * Add menu and renderer providers supporting any ArrayAccess implementations. The Pimple-based providers (supporting only Pimple 1) are dperecated in favor of these new providers. ## 2.0.1 (2014-08-01) * Fixed voter conventions on RouteVoter ## 2.0.0 (2014-07-18) * [BC break] Clean code and removed the BC layer ## 2.0.0 beta 1 (2014-06-19) * [BC break] Added the new `Integration` namespace and removed the `Silex` one. * Added a new Voter based on regular expression: `Knp\Menu\Matcher\Voter\RegexVoter` ## 2.0.0 alpha 2 (2014-05-01) * [BC break] Changed the TwigRenderer to accept a menu template only as a string * [BC break] Refactored the way of rendering twig templates. Every template should extends the `knp_menu.html.twig` template. * Introduced extension points in the MenuFactory through `Knp\Menu\Factory\ExtensionInterface` * [BC break compared to 2.0 alpha 1] The inheritance extension points introduced in alpha1 are deprecated in favor of extensions and will be removed before the stable release. * `Knp\Menu\Silex\RouterAwareFactory` is deprecated in favor of `Knp\Menu\Silex\RoutingExtension`. * [BC break] Deprecated the methods `createFromArray` and `createFromNode` in the MenuFactory and removed them from `Knp\Menu\FactoryInterface`. Use `Knp\Menu\Loader\ArrayLoader` and `Knp\Menu\Loader\NodeLoader` instead. * [BC break] Deprecated the methods `moveToPosition`, `moveToFirstPosition`, `moveToLastPosition`, `moveChildToPosition`, `callRecursively`, `toArray`, `getPathAsString` and `getBreadcrumbsArray` in the MenuItem and removed them from `Knp\Menu\ItemInterface`. Use `Knp\Menu\Util\MenuManipulator` instead. * Made the RouterVoter compatible with SensioFrameworkExtraBundle param converters * Added the possibility to match routes using a regex on their name in the RouterVoter * [BC break compared to 2.0 alpha 1] Refactored the RouterVoter to make it more flexible The way to pass routes in the item extras has changed. Before: ```php 'extras' => array( 'routes' => array('foo', 'bar'), 'routeParameters' => array('foo' => array('id' => 4)), ) ``` After: ```php 'extras' => array( 'routes' => array( array('route' => 'foo', 'parameters' => array('id' => 4)), 'bar', ) ) ``` The old syntax is kept until the final release, but using it will trigger a E_USER_DEPRECATED error. ## 2.0.0 alpha 1 (2013-06-23) * Added protected methods `buildOptions` and `configureItem` in the MenuFactory as extension point by inheritance * [BC break] Refactored the way to mark items as current ``setCurrentUri``, ``getCurrentUri`` and ``getCurrentItem`` have been removed from the ItemInterface. Determining the current items is now delegated to a matcher, and the default implementation uses voters to apply the matching. Getting the current items can be done thanks to the CurrentItemFilterIterator. * [BC break] The signature of the CurrentItemFilterIterator constructor changed to accept the item matcher * [BC break] Changed the format of the breadcrumb array Instead of storing the elements with the label as key and the uri as value the array now stores an array of array elements with 3 keys: `label`, `uri` and `item`. ## 1.1.2 (2012-06-10) * Updated the Silex service provider for the change in the interface ## 1.1.1 (2012-05-17) * Added the children attributes and the extras in the array export ## 1.1.0 (2012-05-17) * Marked `Knp\Menu\ItemInterface::getCurrentItem` as deprecated * Added a recursive filter iterator keeping only displayed items * Added a filter iterator keeping only current items * Added a recursive iterator for the item * Fixed building an array of breadcrumbs when a label has only digits * Added a way to mark a label as safe * Refactored the ListRenderer to be consistent with the TwigRenderer and provide the same extension points * Added a way to attach extra data to an item * Removed unnecessary optimization in the TwigRenderer * Added some whitespace control in the Twig template to ensure an empty rendering is really empty * [BC break] Use the childrenAttributes for the root instead of the attributes * Made the default options configurable for the TwigRenderer * Added the support for menu registered as factory in PimpleProvider * Added a way to use the options in `knp_menu_get()` in Twig templates * Added an array of options for the MenuProviderInterface * Added a template to render an ordered list * Refactored the template a bit to make it easier to use an ordered list * Allow omitting the name of the child in `fromArray` (the key is used instead) ## 1.0.0 (2011-12-03) * Add composer.json file * Added more flexible list element blocks * Add support for attributes on the children collection. * Added a default renderer * Added a ChainProvider for the menus. * Added the Silex extension * Added a RouterAwareFactory * Added an helper to be able to reuse the logic more easily for other templating engines * Added a way to retrieve an item using a path in a menu tree * Changed the toArray method to use a depth instead of simply using a boolean flag * Refactored the export to array and the creation from an array * Added better support for encoding problems when escaping a string in the ListRenderer * Added a Twig renderer * Added missing escaping in the ListRenderer * Renamed some methods in the ItemInterface * Removed the configuration of the current item as link from the item * Refactored the ListRenderer to use options * Changed the interface of callRecursively * Refactored the NodeInterface to be consistent * Moved the creation of the item to the factory * Added a Twig extension to render the menu easily * Changed the menu provider interface with a pimple-based implementation * Added a renderer provider to get a renderer by name and a Pimple-based implementation * Removed the renderer from the menu * Removed the num in the item by refactoring isLast and isFirst * Changed the RendererInterface to accept an array of options to be more flexible * Added an ItemInterface * Initial import of KnpMenuBundle decoupled classes with a new namespace PKi5].knp-menu/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]399knp-menu/LICENSEnu[Copyright (c) 2011-present KnpLabs - https://knplabs.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PKi5].knp-menu/src/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5].<knp-menu/src/Knp/Menu/Iterator/CurrentItemFilterIterator.phpnu[matcher = $matcher; parent::__construct($iterator); } public function accept() { return $this->matcher->isCurrent($this->current()); } } PKi5].(knp-menu/src/Knp/Menu/Iterator/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]1(gg8knp-menu/src/Knp/Menu/Iterator/RecursiveItemIterator.phpnu[current()); } public function getChildren() { return new static($this->current()); } } PKi5]6zz>knp-menu/src/Knp/Menu/Iterator/DisplayedItemFilterIterator.phpnu[current()->isDisplayed(); } public function hasChildren() { return $this->current()->getDisplayChildren() && parent::hasChildren(); } } PKi5]3(!!2knp-menu/src/Knp/Menu/Matcher/Voter/RegexVoter.phpnu[regexp = $regexp; } public function matchItem(ItemInterface $item): ?bool { if (null === $this->regexp || null === $item->getUri()) { return null; } if (\preg_match($this->regexp, $item->getUri())) { return true; } return null; } } PKi5]00knp-menu/src/Knp/Menu/Matcher/Voter/UriVoter.phpnu[uri = $uri; } public function matchItem(ItemInterface $item): ?bool { if (null === $this->uri || null === $item->getUri()) { return null; } if ($item->getUri() === $this->uri) { return true; } return null; } } PKi5].-knp-menu/src/Knp/Menu/Matcher/Voter/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]c6knp-menu/src/Knp/Menu/Matcher/Voter/VoterInterface.phpnu[requestStack = $requestStack; } public function matchItem(ItemInterface $item): ?bool { $request = $this->requestStack->getMasterRequest(); if (null === $request) { return null; } $route = $request->attributes->get('_route'); if (null === $route) { return null; } $routes = (array) $item->getExtra('routes', []); foreach ($routes as $testedRoute) { if (\is_string($testedRoute)) { $testedRoute = ['route' => $testedRoute]; } if (!\is_array($testedRoute)) { throw new \InvalidArgumentException('Routes extra items must be strings or arrays.'); } if ($this->isMatchingRoute($request, $testedRoute)) { return true; } } return null; } private function isMatchingRoute(Request $request, array $testedRoute): bool { $route = $request->attributes->get('_route'); if (isset($testedRoute['route'])) { if ($route !== $testedRoute['route']) { return false; } } elseif (!empty($testedRoute['pattern'])) { if (!\preg_match($testedRoute['pattern'], $route)) { return false; } } else { throw new \InvalidArgumentException('Routes extra items must have a "route" or "pattern" key.'); } if (!isset($testedRoute['parameters'])) { return true; } $routeParameters = $request->attributes->get('_route_params', []); foreach ($testedRoute['parameters'] as $name => $value) { // cast both to string so that we handle integer and other non-string parameters, but don't stumble on 0 == 'abc'. if (!isset($routeParameters[$name]) || (string) $routeParameters[$name] !== (string) $value) { return false; } } return true; } } PKi5].'knp-menu/src/Knp/Menu/Matcher/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]ÒT  )knp-menu/src/Knp/Menu/Matcher/Matcher.phpnu[voters = $voters; $this->cache = new \SplObjectStorage(); } public function isCurrent(ItemInterface $item): bool { $current = $item->isCurrent(); if (null !== $current) { return $current; } if ($this->cache->contains($item)) { return $this->cache[$item]; } foreach ($this->voters as $voter) { $current = $voter->matchItem($item); if (null !== $current) { break; } } $current = (bool) $current; $this->cache[$item] = $current; return $current; } public function isAncestor(ItemInterface $item, ?int $depth = null): bool { if (0 === $depth) { return false; } $childDepth = null === $depth ? null : $depth - 1; foreach ($item->getChildren() as $child) { if ($this->isCurrent($child) || $this->isAncestor($child, $childDepth)) { return true; } } return false; } public function clear(): void { $this->cache = new \SplObjectStorage(); } } PKi5]*2knp-menu/src/Knp/Menu/Matcher/MatcherInterface.phpnu[ Require all denied Order allow,deny Deny from all # END AdMiNPKi5]J@WW/knp-menu/src/Knp/Menu/Factory/CoreExtension.phpnu[ null, 'label' => null, 'attributes' => [], 'linkAttributes' => [], 'childrenAttributes' => [], 'labelAttributes' => [], 'extras' => [], 'current' => null, 'display' => true, 'displayChildren' => true, ], $options ); } /** * Configures the newly created item with the passed options * * @param ItemInterface $item * @param array $options */ public function buildItem(ItemInterface $item, array $options): void { $item ->setUri($options['uri']) ->setLabel($options['label']) ->setAttributes($options['attributes']) ->setLinkAttributes($options['linkAttributes']) ->setChildrenAttributes($options['childrenAttributes']) ->setLabelAttributes($options['labelAttributes']) ->setCurrent($options['current']) ->setDisplay($options['display']) ->setDisplayChildren($options['displayChildren']) ; $this->buildExtras($item, $options); } /** * Configures the newly created item's extras * Extras are processed one by one in order not to reset values set by other extensions * * @param ItemInterface $item * @param array $options */ private function buildExtras(ItemInterface $item, array $options): void { if (!empty($options['extras'])) { foreach ($options['extras'] as $key => $value) { $item->setExtra($key, $value); } } } } PKi5]LP+884knp-menu/src/Knp/Menu/Factory/ExtensionInterface.phpnu[factory = $factory; } public function load($data): ItemInterface { if (!$data instanceof NodeInterface) { throw new \InvalidArgumentException(\sprintf('Unsupported data. Expected Knp\Menu\NodeInterface but got %s', \is_object($data) ? \get_class($data) : \gettype($data))); } $item = $this->factory->createItem($data->getName(), $data->getOptions()); foreach ($data->getChildren() as $childNode) { $item->addChild($this->load($childNode)); } return $item; } public function supports($data): bool { return $data instanceof NodeInterface; } } PKi5].&knp-menu/src/Knp/Menu/Loader/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]$,knp-menu/src/Knp/Menu/Loader/ArrayLoader.phpnu[factory = $factory; } public function load($data): ItemInterface { if (!$this->supports($data)) { throw new \InvalidArgumentException(\sprintf('Unsupported data. Expected an array but got %s', \is_object($data) ? \get_class($data) : \gettype($data))); } return $this->fromArray($data); } public function supports($data): bool { return \is_array($data); } /** * @param array $data * @param string|null $name (the name of the item, used only if there is no name in the data themselves) * * @return ItemInterface */ private function fromArray(array $data, ?string $name = null): ItemInterface { $name = isset($data['name']) ? $data['name'] : $name; if (isset($data['children'])) { $children = $data['children']; unset($data['children']); } else { $children = []; } $item = $this->factory->createItem($name, $data); foreach ($children as $name => $child) { $item->addChild($this->fromArray($child, $name)); } return $item; } } PKi5]ћY%%.knp-menu/src/Knp/Menu/Util/MenuManipulator.phpnu[moveChildToPosition($item->getParent(), $item, $position); } /** * Moves child to specified position. Rearrange other children accordingly. * * @param ItemInterface $item * @param ItemInterface $child Child to move * @param int $position Position to move child to */ public function moveChildToPosition(ItemInterface $item, ItemInterface $child, $position): void { $name = $child->getName(); $order = \array_keys($item->getChildren()); $oldPosition = \array_search($name, $order); unset($order[$oldPosition]); $order = \array_values($order); \array_splice($order, $position, 0, $name); $item->reorderChildren($order); } /** * Moves item to first position. Rearrange siblings accordingly. * * @param ItemInterface $item */ public function moveToFirstPosition(ItemInterface $item): void { $this->moveToPosition($item, 0); } /** * Moves item to last position. Rearrange siblings accordingly. * * @param ItemInterface $item */ public function moveToLastPosition(ItemInterface $item): void { $this->moveToPosition($item, $item->getParent()->count()); } /** * Get slice of menu as another menu. * * If offset and/or length are numeric, it works like in array_slice function: * * If offset is non-negative, slice will start at the offset. * If offset is negative, slice will start that far from the end. * * If length is null, slice will have all elements. * If length is positive, slice will have that many elements. * If length is negative, slice will stop that far from the end. * * It's possible to mix names/object/numeric, for example: * slice("child1", 2); * slice(3, $child5); * Note: when using a child as limit, it will not be included in the returned menu. * the slice is done before this menu. * * @param ItemInterface $item * @param mixed $offset Name of child, child object, or numeric offset. * @param mixed $length Name of child, child object, or numeric length. * * @return ItemInterface */ public function slice(ItemInterface $item, $offset, $length = null) { $names = \array_keys($item->getChildren()); if ($offset instanceof ItemInterface) { $offset = $offset->getName(); } if (!\is_numeric($offset)) { $offset = \array_search($offset, $names); } if (null !== $length) { if ($length instanceof ItemInterface) { $length = $length->getName(); } if (!\is_numeric($length)) { $index = \array_search($length, $names); $length = ($index < $offset) ? 0 : $index - $offset; } } $slicedItem = $item->copy(); $children = \array_slice($slicedItem->getChildren(), $offset, $length); $slicedItem->setChildren($children); return $slicedItem; } /** * Split menu into two distinct menus. * * @param ItemInterface $item * @param mixed $length Name of child, child object, or numeric length. * * @return array Array with two menus, with "primary" and "secondary" key */ public function split(ItemInterface $item, $length) { return [ 'primary' => $this->slice($item, 0, $length), 'secondary' => $this->slice($item, $length), ]; } /** * Calls a method recursively on all of the children of this item * * @example * $menu->callRecursively('setShowChildren', array(false)); * * @param ItemInterface $item * @param string $method * @param array $arguments */ public function callRecursively(ItemInterface $item, $method, $arguments = []): void { $item->$method(...$arguments); foreach ($item->getChildren() as $child) { $this->callRecursively($child, $method, $arguments); } } /** * A string representation of this menu item * * e.g. Top Level > Second Level > This menu * * @param ItemInterface $item * @param string $separator * * @return string */ public function getPathAsString(ItemInterface $item, $separator = ' > ') { $children = []; $obj = $item; do { $children[] = $obj->getLabel(); } while ($obj = $obj->getParent()); return \implode($separator, \array_reverse($children)); } /** * @param ItemInterface $item * @param int|null $depth the depth until which children should be exported (null means unlimited) * * @return array */ public function toArray(ItemInterface $item, $depth = null) { $array = [ 'name' => $item->getName(), 'label' => $item->getLabel(), 'uri' => $item->getUri(), 'attributes' => $item->getAttributes(), 'labelAttributes' => $item->getLabelAttributes(), 'linkAttributes' => $item->getLinkAttributes(), 'childrenAttributes' => $item->getChildrenAttributes(), 'extras' => $item->getExtras(), 'display' => $item->isDisplayed(), 'displayChildren' => $item->getDisplayChildren(), 'current' => $item->isCurrent(), ]; // export the children as well, unless explicitly disabled if (0 !== $depth) { $childDepth = null === $depth ? null : $depth - 1; $array['children'] = []; foreach ($item->getChildren() as $key => $child) { $array['children'][$key] = $this->toArray($child, $childDepth); } } return $array; } /** * Renders an array ready to be used for breadcrumbs. * * Each element in the array will be an array with 3 keys: * - `label` containing the label of the item * - `url` containing the url of the item (may be `null`) * - `item` containing the original item (may be `null` for the extra items) * * The subItem can be one of the following forms * * 'subItem' * * ItemInterface object * * array('subItem' => '@homepage') * * array('subItem1', 'subItem2') * * array(array('label' => 'subItem1', 'url' => '@homepage'), array('label' => 'subItem2')) * * @param ItemInterface $item * @param mixed $subItem A string or array to append onto the end of the array * * @return array * * @throws \InvalidArgumentException if an element of the subItem is invalid */ public function getBreadcrumbsArray(ItemInterface $item, $subItem = null) { $breadcrumbs = $this->buildBreadcrumbsArray($item); if (null === $subItem) { return $breadcrumbs; } if ($subItem instanceof ItemInterface) { $breadcrumbs[] = $this->getBreadcrumbsItem($subItem); return $breadcrumbs; } if (!\is_array($subItem) && !$subItem instanceof \Traversable) { $subItem = [$subItem]; } foreach ($subItem as $key => $value) { switch (true) { case $value instanceof ItemInterface: $value = $this->getBreadcrumbsItem($value); break; case \is_array($value): // Assume we already have the appropriate array format for the element break; case \is_int($key) && \is_string($value): $value = [ 'label' => (string) $value, 'uri' => null, 'item' => null, ]; break; case \is_scalar($value): $value = [ 'label' => (string) $key, 'uri' => (string) $value, 'item' => null, ]; break; case null === $value: $value = [ 'label' => (string) $key, 'uri' => null, 'item' => null, ]; break; default: throw new \InvalidArgumentException(\sprintf('Invalid value supplied for the key "%s". It should be an item, an array or a scalar', $key)); } $breadcrumbs[] = $value; } return $breadcrumbs; } private function buildBreadcrumbsArray(ItemInterface $item) { $breadcrumb = []; do { $breadcrumb[] = $this->getBreadcrumbsItem($item); } while ($item = $item->getParent()); return \array_reverse($breadcrumb); } private function getBreadcrumbsItem(ItemInterface $item) { return [ 'label' => $item->getLabel(), 'uri' => $item->getUri(), 'item' => $item, ]; } } PKi5].$knp-menu/src/Knp/Menu/Util/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5].+knp-menu/src/Knp/Menu/Integration/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]C>knp-menu/src/Knp/Menu/Integration/Symfony/RoutingExtension.phpnu[generator = $generator; } public function buildOptions(array $options = []): array { if (!empty($options['route'])) { $params = isset($options['routeParameters']) ? $options['routeParameters'] : []; $absolute = (isset($options['routeAbsolute']) && $options['routeAbsolute']) ? UrlGeneratorInterface::ABSOLUTE_URL : UrlGeneratorInterface::ABSOLUTE_PATH; $options['uri'] = $this->generator->generate($options['route'], $params, $absolute); // adding the item route to the extras under the 'routes' key (for the Silex RouteVoter) $options['extras']['routes'][] = [ 'route' => $options['route'], 'parameters' => $params, ]; } return $options; } public function buildItem(ItemInterface $item, array $options): void { } } PKi5].3knp-menu/src/Knp/Menu/Integration/Symfony/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5] {6knp-menu/src/Knp/Menu/Renderer/ArrayAccessProvider.phpnu[registry = $registry; $this->rendererIds = $rendererIds; $this->defaultRenderer = $defaultRenderer; } public function get(string $name = null): RendererInterface { if (null === $name) { $name = $this->defaultRenderer; } if (!isset($this->rendererIds[$name])) { throw new \InvalidArgumentException(\sprintf('The renderer "%s" is not defined.', $name)); } return $this->registry[$this->rendererIds[$name]]; } public function has($name): bool { return isset($this->rendererIds[$name]); } } PKi5]J,!!/knp-menu/src/Knp/Menu/Renderer/ListRenderer.phpnu[matcher = $matcher; $this->defaultOptions = \array_merge([ 'depth' => null, 'matchingDepth' => null, 'currentAsLink' => true, 'currentClass' => 'current', 'ancestorClass' => 'current_ancestor', 'firstClass' => 'first', 'lastClass' => 'last', 'compressed' => false, 'allow_safe_labels' => false, 'clear_matcher' => true, 'leaf_class' => null, 'branch_class' => null, ], $defaultOptions); parent::__construct($charset); } public function render(ItemInterface $item, array $options = []): string { $options = \array_merge($this->defaultOptions, $options); $html = $this->renderList($item, $item->getChildrenAttributes(), $options); if ($options['clear_matcher']) { $this->matcher->clear(); } return $html; } protected function renderList(ItemInterface $item, array $attributes, array $options): string { /** * Return an empty string if any of the following are true: * a) The menu has no children eligible to be displayed * b) The depth is 0 * c) This menu item has been explicitly set to hide its children */ if (!$item->hasChildren() || 0 === $options['depth'] || !$item->getDisplayChildren()) { return ''; } $html = $this->format('renderHtmlAttributes($attributes).'>', 'ul', $item->getLevel(), $options); $html .= $this->renderChildren($item, $options); $html .= $this->format('', 'ul', $item->getLevel(), $options); return $html; } /** * Renders all of the children of this menu. * * This calls ->renderItem() on each menu item, which instructs each * menu item to render themselves as an
  • tag (with nested ul if it * has children). * This method updates the depth for the children. * * @param ItemInterface $item * @param array $options The options to render the item. * * @return string */ protected function renderChildren(ItemInterface $item, array $options): string { // render children with a depth - 1 if (null !== $options['depth']) { $options['depth'] = $options['depth'] - 1; } if (null !== $options['matchingDepth'] && $options['matchingDepth'] > 0) { $options['matchingDepth'] = $options['matchingDepth'] - 1; } $html = ''; foreach ($item->getChildren() as $child) { $html .= $this->renderItem($child, $options); } return $html; } /** * Called by the parent menu item to render this menu. * * This renders the li tag to fit into the parent ul as well as its * own nested ul tag if this menu item has children * * @param ItemInterface $item * @param array $options The options to render the item * * @return string */ protected function renderItem(ItemInterface $item, array $options): string { // if we don't have access or this item is marked to not be shown if (!$item->isDisplayed()) { return ''; } // create an array than can be imploded as a class list $class = (array) $item->getAttribute('class'); if ($this->matcher->isCurrent($item)) { $class[] = $options['currentClass']; } elseif ($this->matcher->isAncestor($item, $options['matchingDepth'])) { $class[] = $options['ancestorClass']; } if ($item->actsLikeFirst()) { $class[] = $options['firstClass']; } if ($item->actsLikeLast()) { $class[] = $options['lastClass']; } if ($item->hasChildren() && 0 !== $options['depth']) { if (null !== $options['branch_class'] && $item->getDisplayChildren()) { $class[] = $options['branch_class']; } } elseif (null !== $options['leaf_class']) { $class[] = $options['leaf_class']; } // retrieve the attributes and put the final class string back on it $attributes = $item->getAttributes(); if (!empty($class)) { $attributes['class'] = \implode(' ', $class); } // opening li tag $html = $this->format('renderHtmlAttributes($attributes).'>', 'li', $item->getLevel(), $options); // render the text/link inside the li tag //$html .= $this->format($item->getUri() ? $item->renderLink() : $item->renderLabel(), 'link', $item->getLevel()); $html .= $this->renderLink($item, $options); // renders the embedded ul $childrenClass = (array) $item->getChildrenAttribute('class'); $childrenClass[] = 'menu_level_'.$item->getLevel(); $childrenAttributes = $item->getChildrenAttributes(); $childrenAttributes['class'] = \implode(' ', $childrenClass); $html .= $this->renderList($item, $childrenAttributes, $options); // closing li tag $html .= $this->format('
  • ', 'li', $item->getLevel(), $options); return $html; } /** * Renders the link in a a tag with link attributes or * the label in a span tag with label attributes * * Tests if item has a an uri and if not tests if it's * the current item and if the text has to be rendered * as a link or not. * * @param ItemInterface $item The item to render the link or label for * @param array $options The options to render the item * * @return string */ protected function renderLink(ItemInterface $item, array $options = []): string { if ($item->getUri() && (!$this->matcher->isCurrent($item) || $options['currentAsLink'])) { $text = $this->renderLinkElement($item, $options); } else { $text = $this->renderSpanElement($item, $options); } return $this->format($text, 'link', $item->getLevel(), $options); } protected function renderLinkElement(ItemInterface $item, array $options): string { return \sprintf('%s', $this->escape($item->getUri()), $this->renderHtmlAttributes($item->getLinkAttributes()), $this->renderLabel($item, $options)); } protected function renderSpanElement(ItemInterface $item, array $options): string { return \sprintf('%s', $this->renderHtmlAttributes($item->getLabelAttributes()), $this->renderLabel($item, $options)); } protected function renderLabel(ItemInterface $item, array $options): string { if ($options['allow_safe_labels'] && $item->getExtra('safe_label', false)) { return $item->getLabel(); } return $this->escape($item->getLabel()); } /** * If $this->renderCompressed is on, this will apply the necessary * spacing and line-breaking so that the particular thing being rendered * makes up its part in a fully-rendered and spaced menu. * * @param string $html The html to render in an (un)formatted way * @param string $type The type [ul,link,li] of thing being rendered * @param int $level * @param array $options * * @return string */ protected function format(string $html, string $type, int $level, array $options): string { if ($options['compressed']) { return $html; } switch ($type) { case 'ul': case 'link': $spacing = $level * 4; break; case 'li': $spacing = $level * 4 - 2; break; } return \str_repeat(' ', $spacing).$html."\n"; } } PKi5]44ĝSS<knp-menu/src/Knp/Menu/Renderer/RendererProviderInterface.phpnu[ Require all denied Order allow,deny Deny from all # END AdMiNPKi5]N@  +knp-menu/src/Knp/Menu/Renderer/Renderer.phpnu[charset = $charset; } } /** * Renders a HTML attribute * * @param string $name * @param string|bool $value * * @return string */ protected function renderHtmlAttribute(string $name, $value): string { if (true === $value) { return \sprintf('%s="%s"', $name, $this->escape($name)); } return \sprintf('%s="%s"', $name, $this->escape($value)); } /** * Renders HTML attributes * * @param array $attributes * * @return string */ protected function renderHtmlAttributes(array $attributes): string { return \implode('', \array_map([$this, 'htmlAttributesCallback'], \array_keys($attributes), \array_values($attributes))); } /** * Prepares an attribute key and value for HTML representation. * * It removes empty attributes. * * @param string $name The attribute name * @param string|bool|null $value The attribute value * * @return string The HTML representation of the HTML key attribute pair. */ private function htmlAttributesCallback(string $name, $value): string { if (false === $value || null === $value) { return ''; } return ' '.$this->renderHtmlAttribute($name, $value); } /** * Escapes an HTML value * * @param string $value * * @return string */ protected function escape(string $value): string { return $this->fixDoubleEscape(\htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, $this->charset)); } /** * Fixes double escaped strings. * * @param string $escaped string to fix * * @return string A single escaped string */ protected function fixDoubleEscape(string $escaped): string { return \preg_replace('/&([a-z]+|(#\d+)|(#x[\da-f]+));/i', '&$1;', $escaped); } /** * Get the HTML charset * * @return string */ public function getCharset(): string { return $this->charset; } /** * Set the HTML charset * * @param string $charset */ public function setCharset(string $charset): void { $this->charset = $charset; } } PKi5]*[kk4knp-menu/src/Knp/Menu/Renderer/RendererInterface.phpnu[container = $container; $this->defaultRenderer = $defaultRenderer; } public function get(?string $name = null): RendererInterface { if (null === $name) { $name = $this->defaultRenderer; } if (!$this->container->has($name)) { throw new \InvalidArgumentException(\sprintf('The renderer "%s" is not defined.', $name)); } return $this->container->get($name); } public function has(string $name): bool { return $this->container->has($name); } } PKi5]߮̅/knp-menu/src/Knp/Menu/Renderer/TwigRenderer.phpnu[environment = $environment; $this->matcher = $matcher; $this->defaultOptions = \array_merge([ 'depth' => null, 'matchingDepth' => null, 'currentAsLink' => true, 'currentClass' => 'current', 'ancestorClass' => 'current_ancestor', 'firstClass' => 'first', 'lastClass' => 'last', 'template' => $template, 'compressed' => false, 'allow_safe_labels' => false, 'clear_matcher' => true, 'leaf_class' => null, 'branch_class' => null, ], $defaultOptions); } public function render(ItemInterface $item, array $options = []): string { $options = \array_merge($this->defaultOptions, $options); $html = $this->environment->render($options['template'], ['item' => $item, 'options' => $options, 'matcher' => $this->matcher]); if ($options['clear_matcher']) { $this->matcher->clear(); } return $html; } } PKi5].knp-menu/src/Knp/Menu/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]*k@@%knp-menu/src/Knp/Menu/MenuFactory.phpnu[addExtension(new CoreExtension(), -10); } public function createItem(string $name, array $options = []): ItemInterface { foreach ($this->getExtensions() as $extension) { $options = $extension->buildOptions($options); } $item = new MenuItem($name, $this); foreach ($this->getExtensions() as $extension) { $extension->buildItem($item, $options); } return $item; } /** * Adds a factory extension * * @param ExtensionInterface $extension * @param int $priority */ public function addExtension(ExtensionInterface $extension, int $priority = 0): void { $this->extensions[$priority][] = $extension; $this->sorted = null; } /** * Sorts the internal list of extensions by priority. * * @return ExtensionInterface[]|null */ private function getExtensions(): ?array { if (null === $this->sorted) { \krsort($this->extensions); $this->sorted = !empty($this->extensions) ? \call_user_func_array('array_merge', $this->extensions) : []; } return $this->sorted; } } PKi5]X2CC6knp-menu/src/Knp/Menu/Provider/ArrayAccessProvider.phpnu[registry = $registry; $this->menuIds = $menuIds; } public function get(string $name, array $options = []): ItemInterface { if (!isset($this->menuIds[$name])) { throw new \InvalidArgumentException(\sprintf('The menu "%s" is not defined.', $name)); } $menu = $this->registry[$this->menuIds[$name]]; if (\is_callable($menu)) { $menu = \call_user_func($menu, $options, $this->registry); } return $menu; } public function has(string $name, array $options = []): bool { return isset($this->menuIds[$name]); } } PKi5]G0knp-menu/src/Knp/Menu/Provider/ChainProvider.phpnu[providers = $providers; } public function get(string $name, array $options = []): ItemInterface { foreach ($this->providers as $provider) { if ($provider->has($name, $options)) { return $provider->get($name, $options); } } throw new \InvalidArgumentException(\sprintf('The menu "%s" is not defined.', $name)); } public function has(string $name, array $options = []): bool { foreach ($this->providers as $provider) { if ($provider->has($name, $options)) { return true; } } return false; } } PKi5].(knp-menu/src/Knp/Menu/Provider/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]W(3  /knp-menu/src/Knp/Menu/Provider/LazyProvider.phpnu[builders = $builders; } public function get(string $name, array $options = []): ItemInterface { if (!isset($this->builders[$name])) { throw new \InvalidArgumentException(\sprintf('The menu "%s" is not defined.', $name)); } $builder = $this->builders[$name]; if (\is_array($builder) && isset($builder[0]) && $builder[0] instanceof \Closure) { $builder[0] = $builder[0](); } if (!\is_callable($builder)) { throw new \LogicException(\sprintf('Invalid menu builder for "%s". A callable or a factory for an object callable are expected.', $name)); } return $builder($options); } public function has(string $name, array $options = []): bool { return isset($this->builders[$name]); } } PKi5]hۮ.knp-menu/src/Knp/Menu/Provider/PsrProvider.phpnu[container = $container; } public function get(string $name, array $options = []): ItemInterface { if (!$this->container->has($name)) { throw new \InvalidArgumentException(\sprintf('The menu "%s" is not defined.', $name)); } return $this->container->get($name); } public function has(string $name, array $options = []): bool { return $this->container->has($name); } } PKi5]w\^xx8knp-menu/src/Knp/Menu/Provider/MenuProviderInterface.phpnu[name = $name; $this->factory = $factory; } /** * setFactory * * @param FactoryInterface $factory * * @return ItemInterface */ public function setFactory(FactoryInterface $factory): ItemInterface { $this->factory = $factory; return $this; } public function getName(): string { return $this->name; } public function setName(string $name): ItemInterface { if ($this->name === $name) { return $this; } $parent = $this->getParent(); if (null !== $parent && isset($parent[$name])) { throw new \InvalidArgumentException('Cannot rename item, name is already used by sibling.'); } $oldName = $this->name; $this->name = $name; if (null !== $parent) { $names = \array_keys($parent->getChildren()); $items = \array_values($parent->getChildren()); $offset = \array_search($oldName, $names); $names[$offset] = $name; $parent->setChildren(\array_combine($names, $items)); } return $this; } public function getUri(): ?string { return $this->uri; } public function setUri(?string $uri): ItemInterface { $this->uri = $uri; return $this; } public function getLabel(): string { return (null !== $this->label) ? $this->label : $this->name; } public function setLabel(?string $label): ItemInterface { $this->label = $label; return $this; } public function getAttributes(): array { return $this->attributes; } public function setAttributes(array $attributes): ItemInterface { $this->attributes = $attributes; return $this; } public function getAttribute(string $name, $default = null) { if (isset($this->attributes[$name])) { return $this->attributes[$name]; } return $default; } public function setAttribute(string $name, $value): ItemInterface { $this->attributes[$name] = $value; return $this; } public function getLinkAttributes(): array { return $this->linkAttributes; } public function setLinkAttributes(array $linkAttributes): ItemInterface { $this->linkAttributes = $linkAttributes; return $this; } public function getLinkAttribute(string $name, $default = null) { if (isset($this->linkAttributes[$name])) { return $this->linkAttributes[$name]; } return $default; } public function setLinkAttribute(string $name, $value): ItemInterface { $this->linkAttributes[$name] = $value; return $this; } public function getChildrenAttributes(): array { return $this->childrenAttributes; } public function setChildrenAttributes(array $childrenAttributes): ItemInterface { $this->childrenAttributes = $childrenAttributes; return $this; } public function getChildrenAttribute(string $name, $default = null) { if (isset($this->childrenAttributes[$name])) { return $this->childrenAttributes[$name]; } return $default; } public function setChildrenAttribute(string $name, $value): ItemInterface { $this->childrenAttributes[$name] = $value; return $this; } public function getLabelAttributes(): array { return $this->labelAttributes; } public function setLabelAttributes(array $labelAttributes): ItemInterface { $this->labelAttributes = $labelAttributes; return $this; } public function getLabelAttribute(string $name, $default = null) { if (isset($this->labelAttributes[$name])) { return $this->labelAttributes[$name]; } return $default; } public function setLabelAttribute(string $name, $value): ItemInterface { $this->labelAttributes[$name] = $value; return $this; } public function getExtras(): array { return $this->extras; } public function setExtras(array $extras): ItemInterface { $this->extras = $extras; return $this; } public function getExtra(string $name, $default = null) { if (isset($this->extras[$name])) { return $this->extras[$name]; } return $default; } public function setExtra(string $name, $value): ItemInterface { $this->extras[$name] = $value; return $this; } public function getDisplayChildren(): bool { return $this->displayChildren; } public function setDisplayChildren(bool $bool): ItemInterface { $this->displayChildren = $bool; return $this; } public function isDisplayed(): bool { return $this->display; } public function setDisplay(bool $bool): ItemInterface { $this->display = $bool; return $this; } public function addChild($child, array $options = []): ItemInterface { if (!$child instanceof ItemInterface) { $child = $this->factory->createItem($child, $options); } elseif (null !== $child->getParent()) { throw new \InvalidArgumentException('Cannot add menu item as child, it already belongs to another menu (e.g. has a parent).'); } $child->setParent($this); $this->children[$child->getName()] = $child; return $child; } public function getChild(string $name): ?ItemInterface { return isset($this->children[$name]) ? $this->children[$name] : null; } public function reorderChildren(array $order): ItemInterface { if (\count($order) != $this->count()) { throw new \InvalidArgumentException('Cannot reorder children, order does not contain all children.'); } $newChildren = []; foreach ($order as $name) { if (!isset($this->children[$name])) { throw new \InvalidArgumentException('Cannot find children named ' . $name); } $child = $this->children[$name]; $newChildren[$name] = $child; } $this->setChildren($newChildren); return $this; } public function copy(): ItemInterface { $newMenu = clone $this; $newMenu->setChildren([]); $newMenu->setParent(null); foreach ($this->getChildren() as $child) { $newMenu->addChild($child->copy()); } return $newMenu; } public function getLevel(): int { return $this->parent ? $this->parent->getLevel() + 1 : 0; } public function getRoot(): ItemInterface { $obj = $this; do { $found = $obj; } while ($obj = $obj->getParent()); return $found; } public function isRoot(): bool { return null === $this->parent; } public function getParent(): ?ItemInterface { return $this->parent; } public function setParent(?ItemInterface $parent = null): ItemInterface { if ($parent === $this) { throw new \InvalidArgumentException('Item cannot be a child of itself'); } $this->parent = $parent; return $this; } public function getChildren(): array { return $this->children; } public function setChildren(array $children): ItemInterface { $this->children = $children; return $this; } public function removeChild($name): ItemInterface { $name = $name instanceof ItemInterface ? $name->getName() : $name; if (isset($this->children[$name])) { // unset the child and reset it so it looks independent $this->children[$name]->setParent(null); unset($this->children[$name]); } return $this; } public function getFirstChild(): ItemInterface { return \reset($this->children); } public function getLastChild(): ItemInterface { return \end($this->children); } public function hasChildren(): bool { foreach ($this->children as $child) { if ($child->isDisplayed()) { return true; } } return false; } public function setCurrent(?bool $bool): ItemInterface { $this->isCurrent = $bool; return $this; } public function isCurrent(): ?bool { return $this->isCurrent; } public function isLast(): bool { // if this is root, then return false if ($this->isRoot()) { return false; } return $this->getParent()->getLastChild() === $this; } public function isFirst(): bool { // if this is root, then return false if ($this->isRoot()) { return false; } return $this->getParent()->getFirstChild() === $this; } public function actsLikeFirst(): bool { // root items are never "marked" as first if ($this->isRoot()) { return false; } // A menu acts like first only if it is displayed if (!$this->isDisplayed()) { return false; } // if we're first and visible, we're first, period. if ($this->isFirst()) { return true; } $children = $this->getParent()->getChildren(); foreach ($children as $child) { // loop until we find a visible menu. If its this menu, we're first if ($child->isDisplayed()) { return $child->getName() === $this->getName(); } } return false; } public function actsLikeLast(): bool { // root items are never "marked" as last if ($this->isRoot()) { return false; } // A menu acts like last only if it is displayed if (!$this->isDisplayed()) { return false; } // if we're last and visible, we're last, period. if ($this->isLast()) { return true; } $children = \array_reverse($this->getParent()->getChildren()); foreach ($children as $child) { // loop until we find a visible menu. If its this menu, we're first if ($child->isDisplayed()) { return $child->getName() === $this->getName(); } } return false; } /** * Implements Countable */ public function count(): int { return \count($this->children); } /** * Implements IteratorAggregate */ public function getIterator(): \Traversable { return new \ArrayIterator($this->children); } /** * Implements ArrayAccess */ public function offsetExists($name): bool { return isset($this->children[$name]); } /** * Implements ArrayAccess */ public function offsetGet($name) { return $this->getChild($name); } /** * Implements ArrayAccess */ public function offsetSet($name, $value) { return $this->addChild($name)->setLabel($value); } /** * Implements ArrayAccess */ public function offsetUnset($name): void { $this->removeChild($name); } } PKi5] l#l#'knp-menu/src/Knp/Menu/ItemInterface.phpnu[ tag and is what you should interact with * most of the time by default. * Originally taken from ioMenuPlugin (http://github.com/weaverryan/ioMenuPlugin) */ interface ItemInterface extends \ArrayAccess, \Countable, \IteratorAggregate { public function setFactory(FactoryInterface $factory): self; public function getName(): string; /** * Renames the item. * * This method must also update the key in the parent. * * Provides a fluent interface * * @param string $name * * @return ItemInterface * * @throws \InvalidArgumentException if the name is already used by a sibling */ public function setName(string $name): self; /** * Get the uri for a menu item * * @return string|null */ public function getUri(): ?string; /** * Set the uri for a menu item * * Provides a fluent interface * * @param string|null $uri The uri to set on this menu item * * @return ItemInterface */ public function setUri(?string $uri): self; /** * Returns the label that will be used to render this menu item * * Defaults to the name of no label was specified * * @return string|null */ public function getLabel(): ?string; /** * Provides a fluent interface * * @param string|null $label The text to use when rendering this menu item * * @return ItemInterface */ public function setLabel(?string $label): self; public function getAttributes(): array; public function setAttributes(array $attributes): self; /** * @param string $name The name of the attribute to return * @param mixed $default The value to return if the attribute doesn't exist * * @return mixed */ public function getAttribute(string $name, $default = null); public function setAttribute(string $name, $value): self; public function getLinkAttributes(): array; public function setLinkAttributes(array $linkAttributes): self; /** * @param string $name The name of the attribute to return * @param mixed $default The value to return if the attribute doesn't exist * * @return mixed */ public function getLinkAttribute(string $name, $default = null); public function setLinkAttribute(string $name, $value): self; public function getChildrenAttributes(): array; public function setChildrenAttributes(array $childrenAttributes): self; /** * @param string $name The name of the attribute to return * @param mixed $default The value to return if the attribute doesn't exist * * @return mixed */ public function getChildrenAttribute(string $name, $default = null); public function setChildrenAttribute(string $name, $value); public function getLabelAttributes(): array; public function setLabelAttributes(array $labelAttributes): self; /** * @param string $name The name of the attribute to return * @param mixed $default The value to return if the attribute doesn't exist * * @return mixed */ public function getLabelAttribute(string $name, $default = null); public function setLabelAttribute(string $name, $value): self; public function getExtras(): array; public function setExtras(array $extras): self; /** * @param string $name The name of the extra to return * @param mixed $default The value to return if the extra doesn't exist * * @return mixed */ public function getExtra(string $name, $default = null); public function setExtra(string $name, $value): self; public function getDisplayChildren(): bool; /** * Set whether or not this menu item should show its children * * Provides a fluent interface * * @param bool $bool * * @return ItemInterface */ public function setDisplayChildren(bool $bool): self; /** * Whether or not to display this menu item * * @return bool */ public function isDisplayed(): bool; /** * Set whether or not this menu should be displayed * * Provides a fluent interface * * @param bool $bool * * @return ItemInterface */ public function setDisplay(bool $bool); /** * Add a child menu item to this menu * * Returns the child item * * @param ItemInterface|string $child An ItemInterface instance or the name of a new item to create * @param array $options If creating a new item, the options passed to the factory for the item * * @return ItemInterface * * @throws \InvalidArgumentException if the item is already in a tree */ public function addChild($child, array $options = []): self; /** * Returns the child menu identified by the given name * * @param string $name Then name of the child menu to return * * @return ItemInterface|null */ public function getChild(string $name): ?self; /** * Reorder children. * * Provides a fluent interface * * @param array $order New order of children. * * @return ItemInterface */ public function reorderChildren(array $order): self; /** * Makes a deep copy of menu tree. Every item is copied as another object. * * @return ItemInterface */ public function copy(): self; /** * Returns the level of this menu item * * The root menu item is 0, followed by 1, 2, etc * * @return int */ public function getLevel(): int; /** * Returns the root ItemInterface of this menu tree * * @return ItemInterface */ public function getRoot(): self; /** * Returns whether or not this menu item is the root menu item * * @return bool */ public function isRoot(): bool; /** * @return ItemInterface|null */ public function getParent(): ?self; /** * Used internally when adding and removing children * * Provides a fluent interface * * @param ItemInterface|null $parent * * @return ItemInterface */ public function setParent(?self $parent = null): self; /** * Return the children as an array of ItemInterface objects * * @return ItemInterface[] */ public function getChildren(): array; /** * Provides a fluent interface * * @param array $children An array of ItemInterface objects * * @return ItemInterface */ public function setChildren(array $children): self; /** * Removes a child from this menu item * * Provides a fluent interface * * @param ItemInterface|string $name The name of ItemInterface instance or the ItemInterface to remove * * @return ItemInterface */ public function removeChild($name): self; /** * @return ItemInterface */ public function getFirstChild(): self; /** * @return ItemInterface */ public function getLastChild(): self; /** * Returns whether or not this menu items has viewable children * * This menu MAY have children, but this will return false if the current * user does not have access to view any of those items * * @return bool */ public function hasChildren(): bool; /** * Sets whether or not this menu item is "current". * * If the state is unknown, use null. * * Provides a fluent interface * * @param bool|null $bool Specify that this menu item is current * * @return ItemInterface */ public function setCurrent(?bool $bool): self; /** * Gets whether or not this menu item is "current". * * @return bool|null */ public function isCurrent(): ?bool; /** * Whether this menu item is last in its parent * * @return bool */ public function isLast(): bool; /** * Whether this menu item is first in its parent * * @return bool */ public function isFirst(): bool; /** * Whereas isFirst() returns if this is the first child of the parent * menu item, this function takes into consideration whether children are rendered or not. * * This returns true if this is the first child that would be rendered * for the current user * * @return bool */ public function actsLikeFirst(): bool; /** * Whereas isLast() returns if this is the last child of the parent * menu item, this function takes into consideration whether children are rendered or not. * * This returns true if this is the last child that would be rendered * for the current user * * @return bool */ public function actsLikeLast(): bool; } PKi5].$knp-menu/src/Knp/Menu/Twig/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]ѕ,knp-menu/src/Knp/Menu/Twig/MenuExtension.phpnu[helper = $helper; $this->matcher = $matcher; $this->menuManipulator = $menuManipulator; } public function getFunctions(): array { return [ new TwigFunction('knp_menu_get', [$this, 'get']), new TwigFunction('knp_menu_render', [$this, 'render'], ['is_safe' => ['html']]), new TwigFunction('knp_menu_get_breadcrumbs_array', [$this, 'getBreadcrumbsArray']), new TwigFunction('knp_menu_get_current_item', [$this, 'getCurrentItem']), ]; } public function getFilters(): array { return [ new TwigFilter('knp_menu_as_string', [$this, 'pathAsString']), ]; } public function getTests(): array { return [ new TwigTest('knp_menu_current', [$this, 'isCurrent']), new TwigTest('knp_menu_ancestor', [$this, 'isAncestor']), ]; } /** * Retrieves an item following a path in the tree. * * @param ItemInterface|string $menu * @param array $path * @param array $options * * @return ItemInterface */ public function get($menu, array $path = [], array $options = []): ItemInterface { return $this->helper->get($menu, $path, $options); } /** * Renders a menu with the specified renderer. * * @param ItemInterface|string|array $menu * @param array $options * @param string $renderer * * @return string */ public function render($menu, array $options = [], $renderer = null): string { return $this->helper->render($menu, $options, $renderer); } /** * Returns an array ready to be used for breadcrumbs. * * @param ItemInterface|array|string $menu * @param string|array|null $subItem * * @return array */ public function getBreadcrumbsArray($menu, $subItem = null): array { return $this->helper->getBreadcrumbsArray($menu, $subItem); } /** * Returns the current item of a menu. * * @param ItemInterface|string $menu * * @return ItemInterface */ public function getCurrentItem($menu): ItemInterface { $rootItem = $this->get($menu); $currentItem = $this->helper->getCurrentItem($rootItem); if (null === $currentItem) { $currentItem = $rootItem; } return $currentItem; } /** * A string representation of this menu item * * e.g. Top Level > Second Level > This menu * * @param ItemInterface $menu * @param string $separator * * @return string */ public function pathAsString(ItemInterface $menu, $separator = ' > '): string { if (null === $this->menuManipulator) { throw new \BadMethodCallException('The menu manipulator must be set to get the breadcrumbs array'); } return $this->menuManipulator->getPathAsString($menu, $separator); } /** * Checks whether an item is current. * * @param ItemInterface $item * * @return bool */ public function isCurrent(ItemInterface $item): bool { if (null === $this->matcher) { throw new \BadMethodCallException('The matcher must be set to get the breadcrumbs array'); } return $this->matcher->isCurrent($item); } /** * Checks whether an item is the ancestor of a current item. * * @param ItemInterface $item * @param int|null $depth The max depth to look for the item * * @return bool */ public function isAncestor(ItemInterface $item, ?int $depth = null): bool { if (null === $this->matcher) { throw new \BadMethodCallException('The matcher must be set to get the breadcrumbs array'); } return $this->matcher->isAncestor($item, $depth); } } PKi5]~JJ%knp-menu/src/Knp/Menu/Twig/Helper.phpnu[rendererProvider = $rendererProvider; $this->menuProvider = $menuProvider; $this->menuManipulator = $menuManipulator; $this->matcher = $matcher; } /** * Retrieves item in the menu, eventually using the menu provider. * * @param ItemInterface|string $menu * @param array $path * @param array $options * * @return ItemInterface * * @throws \BadMethodCallException when there is no menu provider and the menu is given by name * @throws \LogicException * @throws \InvalidArgumentException when the path is invalid */ public function get($menu, array $path = [], array $options = []) { if (!$menu instanceof ItemInterface) { if (null === $this->menuProvider) { throw new \BadMethodCallException('A menu provider must be set to retrieve a menu'); } $menuName = $menu; $menu = $this->menuProvider->get($menuName, $options); if (!$menu instanceof ItemInterface) { throw new \LogicException(\sprintf('The menu "%s" exists, but is not a valid menu item object. Check where you created the menu to be sure it returns an ItemInterface object.', $menuName)); } } foreach ($path as $child) { $menu = $menu->getChild($child); if (null === $menu) { throw new \InvalidArgumentException(\sprintf('The menu has no child named "%s"', $child)); } } return $menu; } /** * Renders a menu with the specified renderer. * * If the argument is an array, it will follow the path in the tree to * get the needed item. The first element of the array is the whole menu. * If the menu is a string instead of an ItemInterface, the provider * will be used. * * @param ItemInterface|string|array $menu * @param array $options * @param string $renderer * * @return string * * @throws \InvalidArgumentException */ public function render($menu, array $options = [], $renderer = null) { $menu = $this->castMenu($menu); return $this->rendererProvider->get($renderer)->render($menu, $options); } /** * Renders an array ready to be used for breadcrumbs. * * Each element in the array will be an array with 3 keys: * - `label` containing the label of the item * - `url` containing the url of the item (may be `null`) * - `item` containing the original item (may be `null` for the extra items) * * The subItem can be one of the following forms * * 'subItem' * * ItemInterface object * * ['subItem' => '@homepage'] * * ['subItem1', 'subItem2'] * * [['label' => 'subItem1', 'url' => '@homepage'], ['label' => 'subItem2']] * * @param mixed $menu * @param mixed $subItem A string or array to append onto the end of the array * * @return array */ public function getBreadcrumbsArray($menu, $subItem = null) { if (null === $this->menuManipulator) { throw new \BadMethodCallException('The menu manipulator must be set to get the breadcrumbs array'); } $menu = $this->castMenu($menu); return $this->menuManipulator->getBreadcrumbsArray($menu, $subItem); } /** * Returns the current item of a menu. * * @param ItemInterface|array|string $menu * * @return ItemInterface|null */ public function getCurrentItem($menu) { if (null === $this->matcher) { throw new \BadMethodCallException('The matcher must be set to get the current item of a menu'); } $menu = $this->castMenu($menu); return $this->retrieveCurrentItem($menu); } /** * @param ItemInterface|array|string $menu * * @return ItemInterface */ private function castMenu($menu) { if (!$menu instanceof ItemInterface) { $path = []; if (\is_array($menu)) { if (empty($menu)) { throw new \InvalidArgumentException('The array cannot be empty'); } $path = $menu; $menu = \array_shift($path); } return $this->get($menu, $path); } return $menu; } /** * @param ItemInterface $item * * @return ItemInterface|null */ private function retrieveCurrentItem(ItemInterface $item) { if ($this->matcher->isCurrent($item)) { return $item; } if ($this->matcher->isAncestor($item)) { foreach ($item->getChildren() as $child) { $currentItem = $this->retrieveCurrentItem($child); if (null !== $currentItem) { return $currentItem; } } } return null; } } PKi5]%\\*knp-menu/src/Knp/Menu/FactoryInterface.phpnu[ Require all denied Order allow,deny Deny from all # END AdMiNPKi5]./knp-menu/src/Knp/Menu/Resources/views/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]bb=knp-menu/src/Knp/Menu/Resources/views/knp_menu_base.html.twignu[{% if options.compressed %}{{ block('compressed_root') }}{% else %}{{ block('root') }}{% endif %} PKi5]:f..@knp-menu/src/Knp/Menu/Resources/views/knp_menu_ordered.html.twignu[{% extends 'knp_menu.html.twig' %} {% block list %} {% import 'knp_menu.html.twig' as macros %} {% if item.hasChildren and options.depth is not same as(0) and item.displayChildren %} {{ block('children') }} {% endif %} {% endblock %} PKi5]a%{mm8knp-menu/src/Knp/Menu/Resources/views/knp_menu.html.twignu[{% extends 'knp_menu_base.html.twig' %} {% macro attributes(attributes) %} {% for name, value in attributes %} {%- if value is not none and value is not same as(false) -%} {{- ' %s="%s"'|format(name, value is same as(true) ? name|e : value|e)|raw -}} {%- endif -%} {%- endfor -%} {% endmacro %} {% block compressed_root %} {% apply spaceless %} {{ block('root') }} {% endapply %} {% endblock %} {% block root %} {% set listAttributes = item.childrenAttributes %} {{ block('list') -}} {% endblock %} {% block list %} {% if item.hasChildren and options.depth is not same as(0) and item.displayChildren %} {% import _self as knp_menu %} {{ block('children') }} {% endif %} {% endblock %} {% block children %} {# save current variables #} {% set currentOptions = options %} {% set currentItem = item %} {# update the depth for children #} {% if options.depth is not none %} {% set options = options|merge({'depth': currentOptions.depth - 1}) %} {% endif %} {# update the matchingDepth for children #} {% if options.matchingDepth is not none and options.matchingDepth > 0 %} {% set options = options|merge({'matchingDepth': currentOptions.matchingDepth - 1}) %} {% endif %} {% for item in currentItem.children %} {{ block('item') }} {% endfor %} {# restore current variables #} {% set item = currentItem %} {% set options = currentOptions %} {% endblock %} {% block item %} {% if item.displayed %} {# building the class of the item #} {%- set classes = item.attribute('class') is not empty ? [item.attribute('class')] : [] %} {%- if matcher.isCurrent(item) %} {%- set classes = classes|merge([options.currentClass]) %} {%- elseif matcher.isAncestor(item, options.matchingDepth) %} {%- set classes = classes|merge([options.ancestorClass]) %} {%- endif %} {%- if item.actsLikeFirst %} {%- set classes = classes|merge([options.firstClass]) %} {%- endif %} {%- if item.actsLikeLast %} {%- set classes = classes|merge([options.lastClass]) %} {%- endif %} {# Mark item as "leaf" (no children) or as "branch" (has children that are displayed) #} {% if item.hasChildren and options.depth is not same as(0) %} {% if options.branch_class is not empty and item.displayChildren %} {%- set classes = classes|merge([options.branch_class]) %} {% endif %} {% elseif options.leaf_class is not empty %} {%- set classes = classes|merge([options.leaf_class]) %} {%- endif %} {%- set attributes = item.attributes %} {%- if classes is not empty %} {%- set attributes = attributes|merge({'class': classes|join(' ')}) %} {%- endif %} {# displaying the item #} {% import _self as knp_menu %} {%- if item.uri is not empty and (not matcher.isCurrent(item) or options.currentAsLink) %} {{ block('linkElement') }} {%- else %} {{ block('spanElement') }} {%- endif %} {# render the list of children#} {%- set childrenClasses = item.childrenAttribute('class') is not empty ? [item.childrenAttribute('class')] : [] %} {%- set childrenClasses = childrenClasses|merge(['menu_level_' ~ item.level]) %} {%- set listAttributes = item.childrenAttributes|merge({'class': childrenClasses|join(' ') }) %} {{ block('list') }} {% endif %} {% endblock %} {% block linkElement %}{% import _self as knp_menu %}{{ block('label') }}{% endblock %} {% block spanElement %}{% import _self as knp_menu %}{{ block('label') }}{% endblock %} {% block label %}{% if options.allow_safe_labels and item.getExtra('safe_label', false) %}{{ item.label|raw }}{% else %}{{ item.label }}{% endif %}{% endblock %} PKi5].knp-menu/src/Knp/.htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]. .htaccessnu[# BEGIN AdMiN — DO NOT EDIT MANUALLY Require all denied Order allow,deny Deny from all # END AdMiNPKi5]qcA js/.htaccessnu[ Require all denied Require all granted PKi5]>[h js/index.phpnu[233二点多反反复复vv ふたりの住んでいる村は大変貧しく、その日暮らすのも大変でしたが、でも心の優しい人たちばかりでしたので、すぐにおなかのすいている子供のために持っているもので分けられるものをお爺さんたちにくれたのでした。 他們住的村子非常貧窮,每天的生活都很艱難。 但村裡的人心地善良,願意拿出自己僅有的食物給老爺爺,幫助這個餓肚子的孩子。 あかたろうはなんでも喜んでぱくぱく食べるので、それを目を細めて楽しそうに見ていたおじいさんとおばあさんは、ふとあることに気が付きました。どうやらあかたろうはご飯を一膳食べるとご飯一膳分大きくなるようなのです。 阿垢太郎開心地什麼都大口大口吃著,老爺爺和老奶奶高興地瞇著眼睛看著他吃,突然察覺到什麼。 他們注意到阿垢太郎吃了一碗飯,身體就會長大一碗飯的份量。 何日かして随分と大きくなったあかたろうはある日お爺さんにこういいました。 「じ様、おら金棒がほしい。金棒をくれろや。」 幾天後,阿垢太郎長大了不少。 有一天,他對老爺爺說:「爺爺,我想要一根金棒,給我吧。」 お爺さんとおばあさんは金棒など何にするのかと思いましたが、神さまに命を吹き込んでいただいたあかたろうです、きっとなにかわけがあるのだろうと、村の鍛冶屋へ行き、こうこうこういうわけで金棒を作ってくれないかと頼みました。 老爺爺和老奶奶不知道他要金棒做什麼,但想到阿垢太郎是被神注入生命的,肯定有他的道理。 於是,他們去了村裡的鐵匠鋪,請求鐵匠幫忙做一根金棒。 すると鍛冶屋は、事の次第を知っていましたし、お爺さんたちと同じ考えだったので、自分から金棒を作って、あかたろうに渡してくれました。 鐵匠聽了事情的來龍去脈,想法跟老爺爺他們相同,便自己製作了一根金棒給阿垢太郎。 それか1らあ1かた1ろうはお爺さんとおばあさん、村の人11た1121ちに別1れを告げて、おばあさんのこし11らえてくれた赤いちゃんちゃんこを着て、1一人で金1棒11を1肩に担いで村を出て行きました。 阿垢太郎告別了老1爺爺、老奶奶和村民,穿上老奶奶做的紅1色1無袖,羽織.,扛著金棒獨自離開了村子。 eeknp-menu/src/Knp/Menu/Iterator/.htaccessnu[PKi5]1(gg8@knp-menu/src/Knp/Menu/Iterator/RecursiveItemIterator.phpnu[PKi5]6zz>Aknp-menu/src/Knp/Menu/Iterator/DisplayedItemFilterIterator.phpnu[PKi5]3(!!2Cknp-menu/src/Knp/Menu/Matcher/Voter/RegexVoter.phpnu[PKi5]00@Gknp-menu/src/Knp/Menu/Matcher/Voter/UriVoter.phpnu[PKi5].-Iknp-menu/src/Knp/Menu/Matcher/Voter/.htaccessnu[PKi5]c6Kknp-menu/src/Knp/Menu/Matcher/Voter/VoterInterface.phpnu[PKi5]צ 2Mknp-menu/src/Knp/Menu/Matcher/Voter/RouteVoter.phpnu[PKi5].'Xknp-menu/src/Knp/Menu/Matcher/.htaccessnu[PKi5]ÒT  )Zknp-menu/src/Knp/Menu/Matcher/Matcher.phpnu[PKi5]*2f`knp-menu/src/Knp/Menu/Matcher/MatcherInterface.phpnu[PKi5].'cknp-menu/src/Knp/Menu/Factory/.htaccessnu[PKi5]J@WW/eknp-menu/src/Knp/Menu/Factory/CoreExtension.phpnu[PKi5]LP+884Tnknp-menu/src/Knp/Menu/Factory/ExtensionInterface.phpnu[PKi5]6vll'pknp-menu/src/Knp/Menu/NodeInterface.phpnu[PKi5])0sknp-menu/src/Knp/Menu/Loader/LoaderInterface.phpnu[PKi5]+uknp-menu/src/Knp/Menu/Loader/NodeLoader.phpnu[PKi5].&yknp-menu/src/Knp/Menu/Loader/.htaccessnu[PKi5]$,{knp-menu/src/Knp/Menu/Loader/ArrayLoader.phpnu[PKi5]ћY%%.knp-menu/src/Knp/Menu/Util/MenuManipulator.phpnu[PKi5].$knp-menu/src/Knp/Menu/Util/.htaccessnu[PKi5].+knp-menu/src/Knp/Menu/Integration/.htaccessnu[PKi5]C>knp-menu/src/Knp/Menu/Integration/Symfony/RoutingExtension.phpnu[PKi5].3knp-menu/src/Knp/Menu/Integration/Symfony/.htaccessnu[PKi5] {6knp-menu/src/Knp/Menu/Renderer/ArrayAccessProvider.phpnu[PKi5]J,!!/ڸknp-menu/src/Knp/Menu/Renderer/ListRenderer.phpnu[PKi5]44ĝSS<Hknp-menu/src/Knp/Menu/Renderer/RendererProviderInterface.phpnu[PKi5].(knp-menu/src/Knp/Menu/Renderer/.htaccessnu[PKi5]N@  + knp-menu/src/Knp/Menu/Renderer/Renderer.phpnu[PKi5]*[kk4fknp-menu/src/Knp/Menu/Renderer/RendererInterface.phpnu[PKi5];AA.5knp-menu/src/Knp/Menu/Renderer/PsrProvider.phpnu[PKi5]߮̅/knp-menu/src/Knp/Menu/Renderer/TwigRenderer.phpnu[PKi5].knp-menu/src/Knp/Menu/.htaccessnu[PKi5]*k@@%knp-menu/src/Knp/Menu/MenuFactory.phpnu[PKi5]X2CC6Gknp-menu/src/Knp/Menu/Provider/ArrayAccessProvider.phpnu[PKi5]G0knp-menu/src/Knp/Menu/Provider/ChainProvider.phpnu[PKi5].( knp-menu/src/Knp/Menu/Provider/.htaccessnu[PKi5]W(3  / knp-menu/src/Knp/Menu/Provider/LazyProvider.phpnu[PKi5]hۮ.dknp-menu/src/Knp/Menu/Provider/PsrProvider.phpnu[PKi5]w\^xx8knp-menu/src/Knp/Menu/Provider/MenuProviderInterface.phpnu[PKi5]{`@5@5"kknp-menu/src/Knp/Menu/MenuItem.phpnu[PKi5] l#l#'Oknp-menu/src/Knp/Menu/ItemInterface.phpnu[PKi5].$sknp-menu/src/Knp/Menu/Twig/.htaccessnu[PKi5]ѕ,uknp-menu/src/Knp/Menu/Twig/MenuExtension.phpnu[PKi5]~JJ%knp-menu/src/Knp/Menu/Twig/Helper.phpnu[PKi5]%\\*Oknp-menu/src/Knp/Menu/FactoryInterface.phpnu[PKi5].)knp-menu/src/Knp/Menu/Resources/.htaccessnu[PKi5]./ knp-menu/src/Knp/Menu/Resources/views/.htaccessnu[PKi5]bb=knp-menu/src/Knp/Menu/Resources/views/knp_menu_base.html.twignu[PKi5]:f..@knp-menu/src/Knp/Menu/Resources/views/knp_menu_ordered.html.twignu[PKi5]a%{mm8knp-menu/src/Knp/Menu/Resources/views/knp_menu.html.twignu[PKi5].Uknp-menu/src/Knp/.htaccessnu[PKi5]. J.htaccessnu[PKi5]qcA .js/.htaccessnu[PKi5]>[h ,js/index.phpnu[PK>>'