├── .gitignore ├── docker └── dev │ └── php │ ├── app.conf │ └── Dockerfile ├── app ├── config │ ├── packages │ │ ├── routing.yaml │ │ ├── dev │ │ │ └── routing.yaml │ │ ├── test │ │ │ └── framework.yaml │ │ └── framework.yaml │ ├── bundles.php │ ├── routes.yaml │ └── services.yaml ├── .gitignore ├── src │ ├── Exception │ │ ├── StopBotException.php │ │ ├── TimeoutException.php │ │ └── BreakIterationException.php │ ├── Bot │ │ ├── BotInterface.php │ │ └── SimpleBot.php │ ├── Strategy │ │ ├── Strategy.php │ │ ├── SimpleStrategy.php │ │ └── Traits │ │ │ ├── MinimumTradeAmount.php │ │ │ └── PreconfiguredOrders.php │ ├── Kernel.php │ ├── Service │ │ └── KunaClient.php │ └── Command │ │ └── SimpleBotCommand.php ├── .env.dist ├── bin │ └── console ├── simple-bot-config.yaml.dist ├── Makefile ├── composer.json └── composer.lock ├── docker-compose.yml ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docker/dev/php/app.conf: -------------------------------------------------------------------------------- 1 | error_reporting = E_ALL 2 | date.timezone = UTC 3 | -------------------------------------------------------------------------------- /app/config/packages/routing.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | router: 3 | strict_requirements: ~ 4 | -------------------------------------------------------------------------------- /app/config/packages/dev/routing.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | router: 3 | strict_requirements: true 4 | -------------------------------------------------------------------------------- /app/config/bundles.php: -------------------------------------------------------------------------------- 1 | ['all' => true], 5 | ]; 6 | -------------------------------------------------------------------------------- /app/config/packages/test/framework.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | test: ~ 3 | session: 4 | storage_id: session.storage.mock_file 5 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | ###> symfony/framework-bundle ### 2 | .env 3 | /public/bundles/ 4 | /var/ 5 | /vendor/ 6 | *.yaml 7 | ###< symfony/framework-bundle ### 8 | -------------------------------------------------------------------------------- /app/src/Exception/StopBotException.php: -------------------------------------------------------------------------------- 1 | symfony/framework-bundle ### 6 | APP_ENV=dev 7 | APP_DEBUG=1 8 | APP_SECRET=c445b2cfb52cbcb2f7f6a025caf049b4 9 | ###< symfony/framework-bundle ### 10 | 11 | KUNA_URL="https://kuna.io" 12 | KUNA_API_URN="/api/v2" -------------------------------------------------------------------------------- /app/src/Exception/BreakIterationException.php: -------------------------------------------------------------------------------- 1 | timeout = $timeout; 19 | } 20 | 21 | /** 22 | * @return int 23 | */ 24 | public function getTimeout(): int 25 | { 26 | return $this->timeout; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | load(__DIR__.'/../.env'); 21 | } 22 | 23 | $input = new ArgvInput(); 24 | $env = $input->getParameterOption(['--env', '-e'], $_SERVER['APP_ENV'] ?? 'dev'); 25 | $debug = ($_SERVER['APP_DEBUG'] ?? true) !== '0' && !$input->hasParameterOption(['--no-debug', '']); 26 | 27 | if ($debug && class_exists(Debug::class)) { 28 | Debug::enable(); 29 | } 30 | 31 | $kernel = new Kernel($env, $debug); 32 | $application = new Application($kernel); 33 | $application->run($input); 34 | -------------------------------------------------------------------------------- /app/src/Strategy/Strategy.php: -------------------------------------------------------------------------------- 1 | client = $client; 31 | $this->output = $output; 32 | } 33 | 34 | /** 35 | * @return KunaClient 36 | */ 37 | public function getClient(): KunaClient 38 | { 39 | return $this->client; 40 | } 41 | 42 | /** 43 | * @param string $message 44 | * @return void 45 | */ 46 | protected function info(string $message): void 47 | { 48 | $this->output->writeln($message); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/Strategy/SimpleStrategy.php: -------------------------------------------------------------------------------- 1 | getClient()->shared()->asksOrderBook($pair, true); 25 | /** @var Order $topOrder */ 26 | $topOrder = $orders[0]; 27 | 28 | return $topOrder->getPrice(); 29 | } 30 | 31 | /** 32 | * @param string $pair 33 | * @return float 34 | */ 35 | public function getCurrentBuyPrice(string $pair): float 36 | { 37 | /** @var Order $topOrder */ 38 | $topOrder = $this->getClient()->shared()->bidsOrderBook($pair, true)[0]; 39 | 40 | return $topOrder->getPrice(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /docker/dev/php/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM madmis/php7.1-cli:latest 2 | 3 | #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 | RUN echo 'PS1="\[\033[36m\]\u\[\033[m\]@\[\033[95;1m\]kunbo-app:\[\033[34m\]\w\[\033[m\]\$ "' >> ~/.bashrc 5 | #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 | 7 | #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 | COPY app.conf /usr/local/etc/php/php.ini 9 | #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 | 11 | #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12 | RUN pecl install trader \ 13 | && docker-php-ext-enable trader 14 | #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 15 | 16 | RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 17 | 18 | WORKDIR /var/www 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Dmitry 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /app/simple-bot-config.yaml.dist: -------------------------------------------------------------------------------- 1 | # This is example config for Simple Bit (Simple strategy) 2 | # kuna.io api public key 3 | public_key: "" 4 | # kuna.io api secret key 5 | secret_key: "" 6 | 7 | # Trading pair 8 | pair: btcuah 9 | 10 | # Trading pair configuration 11 | base_currency: 12 | # If current value more than base currency account balance 13 | # account balance will be divided to a margin (below) count 14 | # result amount will be - order value 15 | boundary: 0.05 16 | # orders count and margin for each of them 17 | margin: [0.0001, 0.001] 18 | quote_currency: 19 | # If current value more than quote currency account balance 20 | # account balance will be divided to a margin (below) count 21 | # result amount will be - order value 22 | boundary: 400 23 | # orders count and margin for each of them 24 | margin: [50, -50, -150] 25 | 26 | # Minimum amount for each currency to run tradings. 27 | # if currency account balance less than this value, orders is not created 28 | min_amounts: 29 | btc: 0.001 30 | uah: 10 31 | 32 | # Bot iteration timeout - seconds 33 | iteration_timeout: 30 34 | 35 | # debug info. Show bot memory usage 36 | show_memory_usage: true -------------------------------------------------------------------------------- /app/Makefile: -------------------------------------------------------------------------------- 1 | ifndef APP_ENV 2 | include .env 3 | endif 4 | 5 | ###> symfony/framework-bundle ### 6 | CONSOLE := $(shell which bin/console) 7 | sf_console: 8 | ifndef CONSOLE 9 | @printf "Run \033[32mcomposer require cli\033[39m to install the Symfony console.\n" 10 | endif 11 | 12 | cache-clear: 13 | ifdef CONSOLE 14 | @$(CONSOLE) cache:clear --no-warmup 15 | else 16 | @rm -rf var/cache/* 17 | endif 18 | .PHONY: cache-clear 19 | 20 | cache-warmup: cache-clear 21 | ifdef CONSOLE 22 | @$(CONSOLE) cache:warmup 23 | else 24 | @printf "cannot warmup the cache (needs symfony/console)\n" 25 | endif 26 | .PHONY: cache-warmup 27 | 28 | serve_as_sf: sf_console 29 | ifndef CONSOLE 30 | @${MAKE} serve_as_php 31 | endif 32 | @$(CONSOLE) | grep server:start > /dev/null || ${MAKE} serve_as_php 33 | @$(CONSOLE) server:start 34 | 35 | @printf "Quit the server with \033[32;49mbin/console server:stop.\033[39m\n" 36 | 37 | serve_as_php: 38 | @printf "\033[32;49mServer listening on http://127.0.0.1:8000\033[39m\n"; 39 | @printf "Quit the server with CTRL-C.\n" 40 | @printf "Run \033[32mcomposer require symfony/web-server-bundle\033[39m for a better web server\n" 41 | php -S 127.0.0.1:8000 -t public 42 | 43 | serve: 44 | @${MAKE} serve_as_sf 45 | .PHONY: sf_console serve serve_as_sf serve_as_php 46 | ###< symfony/framework-bundle ### 47 | -------------------------------------------------------------------------------- /app/config/services.yaml: -------------------------------------------------------------------------------- 1 | # Put parameters here that don't need to change on each machine where the app is deployed 2 | # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration 3 | parameters: 4 | kuna.url: "https://kuna.io" 5 | kuna.api_urn: "%env(KUNA_API_URN)%" 6 | 7 | services: 8 | # default configuration for services in *this* file 9 | _defaults: 10 | # automatically injects dependencies in your services 11 | autowire: true 12 | # automatically registers your services as commands, event subscribers, etc. 13 | autoconfigure: true 14 | # this means you cannot fetch services directly from the container via $container->get() 15 | # if you need to do this, you can override this setting on individual services 16 | public: false 17 | 18 | # makes classes in src/ available to be used as services 19 | # this creates a service per class whose id is the fully-qualified class name 20 | App\: 21 | resource: '../src/*' 22 | # you can exclude directories or files 23 | # but if a service is unused, it's removed anyway 24 | exclude: '../src/{Entity,Repository,Tests}' 25 | 26 | # controllers are imported separately to make sure they're public 27 | # and have a tag that allows actions to type-hint services 28 | # App\Controller\: 29 | # resource: '../src/Controller' 30 | # public: true 31 | # tags: ['controller.service_arguments'] 32 | -------------------------------------------------------------------------------- /app/src/Strategy/Traits/MinimumTradeAmount.php: -------------------------------------------------------------------------------- 1 | getClient()->getCurrencyAccount($currency); 28 | } catch (ClientException $e) { 29 | $ex = new BreakIterationException($e->getMessage(), $e->getCode(), $e); 30 | $ex->setTimeout(10); 31 | 32 | throw $ex; 33 | } catch (\Throwable $e) { 34 | throw new StopBotException($e->getMessage(), $e->getCode(), $e); 35 | } 36 | 37 | $balance = number_format($account->getBalance(), 8); 38 | $this->info("Available funds: {$balance} {$currency}."); 39 | 40 | $minAmount = $this->getClient()->minTradeAmount($currency); 41 | if ($account->getBalance() < $minAmount) { 42 | 43 | $this->info(sprintf( 44 | "\tCurrent balance less than minimum trading amount (%s)", 45 | number_format($minAmount, 8) 46 | )); 47 | 48 | return false; 49 | } 50 | 51 | return true; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "madmis/kuna-bot", 3 | "type": "project", 4 | "description": "Kuna.io trading bot", 5 | "license": "MIT", 6 | "require": { 7 | "php": "^7.1.3", 8 | "ext-bcmath": "^7.1", 9 | "doctrine/cache": "^1.8@dev", 10 | "madmis/kuna-api": "dev-master", 11 | "monolog/monolog": "^2.0@dev", 12 | "symfony/console": "^4.0@dev", 13 | "symfony/dependency-injection": "^4.0@dev", 14 | "symfony/flex": "^1.0", 15 | "symfony/framework-bundle": "^4.0@dev", 16 | "symfony/options-resolver": "3.3", 17 | "symfony/var-dumper": "^4.0@dev", 18 | "symfony/yaml": "^4.0@dev" 19 | }, 20 | "require-dev": { 21 | "symfony/dotenv": "^4.0@dev" 22 | }, 23 | "minimum-stability": "dev", 24 | "config": { 25 | "preferred-install": { 26 | "*": "dist" 27 | }, 28 | "sort-packages": true 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "App\\": "src/" 33 | } 34 | }, 35 | "autoload-dev": { 36 | "psr-4": { 37 | "App\\Tests\\": "tests/" 38 | } 39 | }, 40 | "scripts": { 41 | "auto-scripts": { 42 | "make cache-warmup": "script" 43 | }, 44 | "post-install-cmd": [ 45 | "@auto-scripts" 46 | ], 47 | "post-update-cmd": [ 48 | "@auto-scripts" 49 | ] 50 | }, 51 | "conflict": { 52 | "symfony/symfony": "*", 53 | "symfony/twig-bundle": "<3.3", 54 | "symfony/debug": "<3.3" 55 | }, 56 | "extra": { 57 | "symfony": { 58 | "id": "01BRC7580P8YDSQR0013CX56RN", 59 | "allow-contrib": false 60 | } 61 | }, 62 | "bin": ["bin/console"] 63 | } 64 | -------------------------------------------------------------------------------- /app/src/Kernel.php: -------------------------------------------------------------------------------- 1 | environment; 20 | } 21 | 22 | public function getLogDir(): string 23 | { 24 | return dirname(__DIR__).'/var/logs'; 25 | } 26 | 27 | public function registerBundles(): iterable 28 | { 29 | $contents = require dirname(__DIR__).'/config/bundles.php'; 30 | foreach ($contents as $class => $envs) { 31 | if (isset($envs['all']) || isset($envs[$this->environment])) { 32 | yield new $class(); 33 | } 34 | } 35 | } 36 | 37 | protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void 38 | { 39 | $confDir = dirname(__DIR__).'/config'; 40 | $loader->load($confDir.'/packages/*'.self::CONFIG_EXTS, 'glob'); 41 | if (is_dir($confDir.'/packages/'.$this->environment)) { 42 | $loader->load($confDir.'/packages/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob'); 43 | } 44 | $loader->load($confDir.'/services'.self::CONFIG_EXTS, 'glob'); 45 | } 46 | 47 | protected function configureRoutes(RouteCollectionBuilder $routes): void 48 | { 49 | $confDir = dirname(__DIR__).'/config'; 50 | if (is_dir($confDir.'/routes/')) { 51 | $routes->import($confDir.'/routes/*'.self::CONFIG_EXTS, '/', 'glob'); 52 | } 53 | if (is_dir($confDir.'/routes/'.$this->environment)) { 54 | $routes->import($confDir.'/routes/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob'); 55 | } 56 | $routes->import($confDir.'/routes'.self::CONFIG_EXTS, '/', 'glob'); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/Strategy/Traits/PreconfiguredOrders.php: -------------------------------------------------------------------------------- 1 | ..., 'price' => ...], ...] 25 | * @throws BreakIterationException 26 | * @throws StopBotException 27 | */ 28 | public function createPreconfiguredOrders( 29 | string $currency, 30 | float $orderPrice, 31 | float $boundary, 32 | array $margin, 33 | bool $isBuyOrder): array 34 | { 35 | try { 36 | $account = $this->getClient()->getCurrencyAccount($currency); 37 | } catch (ClientException $e) { 38 | $ex = new BreakIterationException($e->getMessage(), $e->getCode(), $e); 39 | $ex->setTimeout(10); 40 | 41 | throw $ex; 42 | } catch (\Throwable $e) { 43 | throw new StopBotException($e->getMessage(), $e->getCode(), $e); 44 | } 45 | 46 | if ($account->getBalance() < $boundary) { 47 | $this->info('Account balance less than boundary, so only 1 order can be opened'); 48 | // can create only one order 49 | $margin = array_slice($margin, 0, 1); 50 | } 51 | 52 | $minAmount = $this->getClient()->minTradeAmount($currency); 53 | $volume = $account->getBalance() / count($margin); 54 | if ($volume < $minAmount) { 55 | $volume = $account->getBalance(); 56 | } 57 | 58 | $this->info('Create orders configurations:'); 59 | $orders = []; 60 | foreach ($margin as $key => $orderMargin) { 61 | $orderVolume = $volume; 62 | $price = bcadd($orderPrice, $orderMargin, 6); 63 | if ($isBuyOrder) { 64 | $orderVolume = bcdiv($orderVolume, $price, 6); 65 | } 66 | 67 | $key++; 68 | $this->info("Order #{$key}: volume|{$orderVolume} price|{$price}"); 69 | 70 | $orders[] = ['volume' => $orderVolume, 'price' => $price]; 71 | } 72 | 73 | return $orders; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/Service/KunaClient.php: -------------------------------------------------------------------------------- 1 | 0.01, 30 | 'uah' => 50, 31 | 'kun' => 1, 32 | 'gol' => 1, 33 | 'eth' => 0.01, 34 | 'waves' => 1, 35 | 'bch' => 0.01, 36 | 'gbg' => 1, 37 | ]; 38 | 39 | /** 40 | * @param string $publicKey 41 | * @param string $secretKey 42 | */ 43 | public function __construct($publicKey, $secretKey) 44 | { 45 | parent::__construct('https://kuna.io', $publicKey, $secretKey); 46 | } 47 | 48 | /** 49 | * @param array $amounts 50 | */ 51 | public function setMinTradeAmounts(array $amounts) 52 | { 53 | if ($amounts) { 54 | $this->minTradeAmounts = array_merge($this->minTradeAmounts, $amounts); 55 | } 56 | } 57 | 58 | /** 59 | * @param string $currency 60 | * @return MyAccount 61 | * @throws ClientException 62 | * @throws \LogicException 63 | */ 64 | public function getCurrencyAccount(string $currency): MyAccount 65 | { 66 | // check pair balance. If we have base currency sell it 67 | $accounts = $this->signed()->me(true)->getAccounts(); 68 | $filtered = array_filter($accounts, 69 | function (MyAccount $account) use ($currency) { 70 | return $account->getCurrency() === $currency; 71 | }); 72 | 73 | if (!$filtered) { 74 | throw new \LogicException("Can't find account for currency: {$currency}"); 75 | } 76 | 77 | return reset($filtered); 78 | } 79 | 80 | /** 81 | * @param string $pair 82 | * @return array 83 | */ 84 | public static function splitPair(string $pair): array 85 | { 86 | if ($pair === self::PAIR_WAVESUAH) { 87 | return str_split($pair, 5); 88 | } 89 | 90 | return str_split($pair, 3); 91 | } 92 | 93 | /** 94 | * Get minimal trade amount for currency 95 | * @param string $currency 96 | * @return float 97 | */ 98 | public function minTradeAmount(string $currency): float 99 | { 100 | $res = $this->minTradeAmounts[$currency] ?? 1000; 101 | 102 | return (float)$res; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kuna-bot 2 | 3 | This is php bot with simple strategy to trade bitcoin 4 | on the https://kuna.io/ exchange. 5 | 6 | **Warning!!!** Use this bot at your own risk. 7 | Don't use this bot if you don't understand how it's working or you will lose your money. 8 | 9 | Please look into bot [source code](https://github.com/madmis/kuna-bot/blob/master/app/src/Bot/SimpleBot.php) to understand how it's working 10 | 11 | 12 | ## Table Of Contents 13 | 14 | - [Installation](#installation) 15 | - [Running the bot](#running-the-bot) 16 | - [Run on the local machine](#run-on-the-local-machine) 17 | - [Run in the Docker container](#run-in-the-docker-container) 18 | 19 | 20 | ## Installation 21 | 22 | Download latest release [here](https://github.com/madmis/kuna-bot/releases) 23 | and extract sources to a project (destination) folder **or** clone project 24 | ```bash 25 | $ git clone https://github.com/madmis/kuna-bot.git ~/kuna-bot 26 | ``` 27 | 28 | Create configuration file: 29 | ```bash 30 | $ cp ~/kuna-bot/app/simple-bot-config.yaml.dist ~/kuna-bot/app/conf.btcuah.yaml 31 | ``` 32 | and change configuration parameters with your requirements. 33 | 34 | 35 | ## Running the bot 36 | 37 | You can run bot on the local machine or in the Docker container. 38 | 39 | ### Run on the local machine 40 | To run bot on the local machine please install: 41 | * [php >=7.1.3](http://php.net/manual/en/install.php) 42 | * [php-bcmath](http://php.net/manual/en/book.bc.php) 43 | * [Сomposer](https://getcomposer.org/doc/00-intro.md) 44 | 45 | Then do next steps: 46 | ```bash 47 | $ cd ~/kuna-bot/app 48 | $ composer install 49 | ``` 50 | and run the bot: 51 | ```bash 52 | $ php ~/kuna-bot/app/bin/console simple-bot:run ~/kuna-bot/app/conf.btcuah.yaml 53 | ``` 54 | 55 | 56 | ### Run in the Docker container 57 | To run bot in the Docker container: 58 | * [Install Docker](https://docs.docker.com/engine/installation/) 59 | * [Install Docker Compose](https://docs.docker.com/compose/install/) 60 | 61 | Then do next steps: 62 | ```bash 63 | $ cd ~/kuna-bot 64 | $ docker-compose up -d 65 | $ docker exec -ti kunabot_php_1 bash 66 | ``` 67 | and run the bot: 68 | ```bash 69 | $ php /var/www/bin/console simple-bot:run /var/www/conf.btcuah.yaml 70 | ``` 71 | 72 | ### Concurrent Running 73 | **! Notice** Don't run more than one bot instance for one trading (exchange) account. 74 | 75 | You can run 2 (or more) bot instances from one application/container. 76 | For this create separate trading (exchange) accounts for different pairs. 77 | 78 | To run 2 bot instances: 79 | * Create 2 configuration files, for different pairs 80 | * Create different trading (exchange) accounts and generate API keys for it. 81 | Then put this case to configuration files (each api key in the corresponding config file) 82 | * Run 2 bot instances (in separate terminal windows) 83 | ```bash 84 | $ php ~/kuna-bot/app/bin/console simple-bot:run ~/kuna-bot/app/conf.btcuah.yaml 85 | $ php ~/kuna-bot/app/bin/console simple-bot:run ~/kuna-bot/app/conf.ethuah.yaml 86 | ``` 87 | -------------------------------------------------------------------------------- /app/src/Command/SimpleBotCommand.php: -------------------------------------------------------------------------------- 1 | setName('simple-bot:run') 30 | ->addArgument('config', InputArgument::REQUIRED, 'Strategy configuration file') 31 | ->setDescription('Simple Kuna.io Bot') 32 | ->setHelp( 33 | <<<'EOF' 34 | The %command.name% run bot: 35 | 36 | Run 37 | php %command.full_name% /var/www/conf.btcuah.yaml 38 | EOF 39 | ); 40 | } 41 | 42 | /** 43 | * @param InputInterface $input 44 | * @param OutputInterface $output 45 | * @return void 46 | * @throws \Symfony\Component\Console\Exception\InvalidArgumentException 47 | * @throws \Symfony\Component\Yaml\Exception\ParseException 48 | * @throws \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException 49 | * @throws \Exception 50 | * @throws \RuntimeException 51 | * @throws \LogicException 52 | * @throws \InvalidArgumentException 53 | */ 54 | protected function execute(InputInterface $input, OutputInterface $output) 55 | { 56 | $this->setColors($output); 57 | $this->input = $input; 58 | 59 | $configFile = $input->getArgument('config'); 60 | if (!is_file($configFile) && !file_exists($configFile)) { 61 | throw new \RuntimeException("Can't find configuration file"); 62 | } 63 | $configSrc = file_get_contents($configFile); 64 | 65 | $config = Yaml::parse($configSrc, Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE); 66 | if ($config === null) { 67 | throw new \RuntimeException('Invalid bot configuration'); 68 | } 69 | if (empty($config['pair'])) { 70 | throw new \RuntimeException('Pair is not configured. Try to add pair to config file.'); 71 | } 72 | $pair = $config['pair']; 73 | 74 | $logDir = $this->getContainer()->getParameter('kernel.logs_dir'); 75 | $loggerName = "simple-bot.{$pair}"; 76 | $logger = new Logger($loggerName); 77 | $logger->pushHandler(new StreamHandler("$logDir/{$loggerName}.log", Logger::DEBUG)); 78 | 79 | (new SimpleBot($output, $pair, $configSrc)) 80 | ->setLogger($logger) 81 | ->run(); 82 | } 83 | 84 | /** 85 | * @param OutputInterface $output 86 | */ 87 | protected function setColors(OutputInterface $output) 88 | { 89 | $output->getFormatter()->setStyle('r', new OutputFormatterStyle('red', null)); 90 | $output->getFormatter()->setStyle('g', new OutputFormatterStyle('green', null)); 91 | $output->getFormatter()->setStyle('y', new OutputFormatterStyle('yellow', null)); 92 | $output->getFormatter()->setStyle('b', new OutputFormatterStyle('blue', null)); 93 | $output->getFormatter()->setStyle('m', new OutputFormatterStyle('magenta', null)); 94 | $output->getFormatter()->setStyle('c', new OutputFormatterStyle('cyan', null)); 95 | $output->getFormatter()->setStyle('w', new OutputFormatterStyle('white', null)); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/Bot/SimpleBot.php: -------------------------------------------------------------------------------- 1 | output = $output; 54 | $this->pair = $pair; 55 | 56 | $this->resolveConfiguration($config); 57 | $this->logger = new NullLogger(); 58 | } 59 | 60 | /** 61 | * @return void 62 | * @throws \Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException 63 | */ 64 | public function run(): void 65 | { 66 | $strategy = $this->createStrategy(); 67 | [$base, $quote] = KunaClient::splitPair($this->pair); 68 | $memUsage = $this->config->get('show_memory_usage'); 69 | $timeout = (int)$this->config->get('iteration_timeout'); 70 | 71 | while (true) { 72 | try { 73 | 74 | $this->output->writeln("***************{$base}/{$quote}***************"); 75 | 76 | $this->processBaseFunds($strategy, $base); 77 | 78 | $this->processQuoteFunds($strategy, $base, $quote); 79 | } catch (BreakIterationException $e) { 80 | if ($e->getMessage()) { 81 | $this->output->writeln("{$e->getMessage()}"); 82 | } 83 | sleep($e->getTimeout()); 84 | continue; 85 | } catch (StopBotException $e) { 86 | if ($e->getMessage()) { 87 | $this->output->writeln("{$e->getMessage()}"); 88 | } 89 | break; 90 | } catch (ClientException $e) { 91 | $this->output->writeln("{$e->getMessage()}"); 92 | $context = ['exception' => $e->getTrace()]; 93 | if ($e->hasResponse()) { 94 | $context['response'] = (string)$e->getResponse()->getBody(); 95 | $this->output->writeln("{$context['response']}"); 96 | } 97 | $this->logger->log(Logger::ERROR, $e->getMessage(), $context); 98 | } catch (\TypeError $e) { 99 | $this->output->writeln("Type Error exception: {$e->getMessage()}"); 100 | sleep($timeout); 101 | } catch (\Throwable $e) { 102 | $this->output->writeln("Unhandled exception: {$e->getMessage()}"); 103 | $this->logger->log(Logger::ERROR, $e->getMessage(), [ 104 | 'exception' => $e->getTrace(), 105 | ]); 106 | } finally { 107 | if ($memUsage) { 108 | $usage = memory_get_peak_usage(true) / 1024; 109 | $this->output->writeln(sprintf( 110 | 'Memory usage: %s Kb (%s Mb)', 111 | $usage, 112 | $usage / 1024 113 | )); 114 | } 115 | sleep($timeout); 116 | } 117 | 118 | sleep($timeout); 119 | } 120 | } 121 | 122 | /** 123 | * @param SimpleStrategy $strategy 124 | * @param string $baseCurrency 125 | * @param string $quoteCurrency 126 | * @throws BreakIterationException 127 | * @throws StopBotException 128 | * @throws ClientException 129 | */ 130 | protected function processQuoteFunds(SimpleStrategy $strategy, string $baseCurrency, string $quoteCurrency) 131 | { 132 | $this->output->writeln("Check quote currency ({$quoteCurrency}) balance"); 133 | if ($strategy->isBalanceAllowTrading($quoteCurrency)) { 134 | /** @var ParameterBag $quoteConfig */ 135 | $quoteConfig = $this->config->get('quote_currency'); 136 | 137 | $this->output->writeln("Quote funds ({$quoteCurrency}) processing"); 138 | $this->output->writeln("\tBoundary: {$quoteConfig->get('boundary')}"); 139 | $this->output->writeln(sprintf( 140 | "\tOrders count: %s", 141 | count($quoteConfig->get('margin')) 142 | )); 143 | $this->output->writeln(sprintf( 144 | "\tMargin: %s", 145 | implode(', ', $quoteConfig->get('margin')) 146 | )); 147 | 148 | $orders = $strategy->createPreconfiguredOrders( 149 | $quoteCurrency, 150 | $strategy->getCurrentBuyPrice($this->pair), 151 | $quoteConfig->get('boundary'), 152 | $quoteConfig->get('margin'), 153 | true 154 | ); 155 | 156 | $this->output->writeln("Create {$baseCurrency} BUY orders"); 157 | foreach ($orders as $key => $order) { 158 | $volume = (float)bcdiv($order['volume'], $order['price'], 6); 159 | 160 | $order = $strategy 161 | ->getClient() 162 | ->signed() 163 | ->createBuyOrder($this->pair, $order['volume'], $order['price'], true); 164 | 165 | $key++; 166 | $this->output->writeln("\tOder #{$key}"); 167 | $this->output->writeln("\t\tId: {$order->getId()}"); 168 | $this->output->writeln("\t\tType: {$order->getOrdType()}"); 169 | $this->output->writeln("\t\tPrice: {$order->getPrice()}"); 170 | $this->output->writeln("\t\tSide: {$order->getSide()}"); 171 | $this->output->writeln("\t\tState: {$order->getState()}"); 172 | $this->output->writeln("\t\tVolume: {$order->getVolume()}"); 173 | } 174 | } 175 | } 176 | 177 | 178 | /** 179 | * @param SimpleStrategy $strategy 180 | * @param string $baseCurrency 181 | * @throws BreakIterationException 182 | * @throws StopBotException 183 | * @throws ClientException 184 | */ 185 | protected function processBaseFunds(SimpleStrategy $strategy, string $baseCurrency) 186 | { 187 | $this->output->writeln("Check base currency ({$baseCurrency}) balance"); 188 | if ($strategy->isBalanceAllowTrading($baseCurrency)) { 189 | /** @var ParameterBag $baseConfig */ 190 | $baseConfig = $this->config->get('base_currency'); 191 | 192 | $this->output->writeln("Base funds ({$baseCurrency}) processing"); 193 | $this->output->writeln("\tBoundary: {$baseConfig->get('boundary')}"); 194 | $this->output->writeln(sprintf( 195 | "\tOrders count: %s", 196 | count($baseConfig->get('margin')) 197 | )); 198 | $this->output->writeln(sprintf( 199 | "\tMargin: %s", 200 | implode(', ', $baseConfig->get('margin')) 201 | )); 202 | 203 | $orders = $strategy->createPreconfiguredOrders( 204 | $baseCurrency, 205 | $strategy->getCurrentSellPrice($this->pair), 206 | $baseConfig->get('boundary'), 207 | $baseConfig->get('margin'), 208 | false 209 | ); 210 | 211 | $this->output->writeln("Create {$baseCurrency} SELL orders"); 212 | foreach ($orders as $key => $order) { 213 | $order = $strategy 214 | ->getClient() 215 | ->signed() 216 | ->createSellOrder($this->pair, $order['volume'], $order['price'], true); 217 | 218 | $key++; 219 | $this->output->writeln("\tOder #{$key}"); 220 | $this->output->writeln("\t\tId: {$order->getId()}"); 221 | $this->output->writeln("\t\tType: {$order->getOrdType()}"); 222 | $this->output->writeln("\t\tPrice: {$order->getPrice()}"); 223 | $this->output->writeln("\t\tSide: {$order->getSide()}"); 224 | $this->output->writeln("\t\tState: {$order->getState()}"); 225 | $this->output->writeln("\t\tVolume: {$order->getVolume()}"); 226 | } 227 | } 228 | } 229 | 230 | /** 231 | * @return SimpleStrategy 232 | */ 233 | protected function createStrategy(): SimpleStrategy 234 | { 235 | $client = new KunaClient( 236 | $this->config->get('public_key'), 237 | $this->config->get('secret_key') 238 | ); 239 | $client->setMinTradeAmounts( 240 | $this->config->get('min_amounts') 241 | ); 242 | 243 | return new SimpleStrategy($client, $this->output); 244 | } 245 | 246 | /** 247 | * @param string $config 248 | * @throws \RuntimeException 249 | */ 250 | protected function resolveConfiguration(string $config) 251 | { 252 | $config = Yaml::parse($config, Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE); 253 | if ($config === null) { 254 | throw new \RuntimeException('Invalid bot configuration'); 255 | } 256 | 257 | $resolver = new OptionsResolver(); 258 | $this->configureOptions($resolver); 259 | $this->config = new ParameterBag($resolver->resolve($config)); 260 | 261 | $baseResolver = new OptionsResolver(); 262 | $this->configurePairOptions($baseResolver); 263 | $baseConfig = $baseResolver->resolve( 264 | $this->config->get('base_currency') 265 | ); 266 | $this->config->set('base_currency', new ParameterBag($baseConfig)); 267 | 268 | $quoteResolver = new OptionsResolver(); 269 | $this->configurePairOptions($quoteResolver); 270 | $quoteConfig = $quoteResolver->resolve( 271 | $this->config->get('quote_currency') 272 | ); 273 | $this->config->set('quote_currency', new ParameterBag($quoteConfig)); 274 | } 275 | 276 | /** 277 | * @param OptionsResolver $resolver 278 | */ 279 | protected function configureOptions(OptionsResolver $resolver) 280 | { 281 | $resolver->setDefaults([ 282 | 'min_amounts' => [], 283 | 'show_memory_usage' => false, 284 | 'iteration_timeout' => 30, 285 | ]); 286 | $resolver 287 | ->setRequired([ 288 | 'public_key', 289 | 'secret_key', 290 | 'pair', 291 | 'base_currency', 292 | 'quote_currency', 293 | ]) 294 | ->setAllowedTypes('public_key', 'string') 295 | ->setAllowedTypes('secret_key', 'string') 296 | ->setAllowedTypes('pair', 'string') 297 | ->setAllowedTypes('base_currency', 'array') 298 | ->setAllowedTypes('quote_currency', 'array') 299 | ->setAllowedTypes('min_amounts', 'array') 300 | ->setAllowedTypes('show_memory_usage', 'bool'); 301 | } 302 | 303 | /** 304 | * @param OptionsResolver $resolver 305 | */ 306 | protected function configurePairOptions(OptionsResolver $resolver) 307 | { 308 | $resolver 309 | ->setRequired([ 310 | 'boundary', 311 | 'margin', 312 | ]) 313 | ->setAllowedTypes('boundary', ['float', 'int']) 314 | ->setAllowedTypes('margin', 'array'); 315 | 316 | $resolver->setAllowedValues('margin', function ($value) { 317 | return count($value) > 0; 318 | }); 319 | } 320 | 321 | /** 322 | * @param LoggerInterface $logger 323 | * @return SimpleBot 324 | */ 325 | public function setLogger(LoggerInterface $logger): SimpleBot 326 | { 327 | $this->logger = $logger; 328 | 329 | return $this; 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /app/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "b1f05e5c8e0e321d5f9007cf4e6d52d8", 8 | "packages": [ 9 | { 10 | "name": "doctrine/annotations", 11 | "version": "dev-master", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/doctrine/annotations.git", 15 | "reference": "2497b1f9db56278d3ad2248f9e4bdbbbaa271c3e" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/doctrine/annotations/zipball/2497b1f9db56278d3ad2248f9e4bdbbbaa271c3e", 20 | "reference": "2497b1f9db56278d3ad2248f9e4bdbbbaa271c3e", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "doctrine/lexer": "1.*", 25 | "php": "^7.1" 26 | }, 27 | "require-dev": { 28 | "doctrine/cache": "1.*", 29 | "phpunit/phpunit": "^5.7" 30 | }, 31 | "type": "library", 32 | "extra": { 33 | "branch-alias": { 34 | "dev-master": "1.6.x-dev" 35 | } 36 | }, 37 | "autoload": { 38 | "psr-4": { 39 | "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" 40 | } 41 | }, 42 | "notification-url": "https://packagist.org/downloads/", 43 | "license": [ 44 | "MIT" 45 | ], 46 | "authors": [ 47 | { 48 | "name": "Roman Borschel", 49 | "email": "roman@code-factory.org" 50 | }, 51 | { 52 | "name": "Benjamin Eberlei", 53 | "email": "kontakt@beberlei.de" 54 | }, 55 | { 56 | "name": "Guilherme Blanco", 57 | "email": "guilhermeblanco@gmail.com" 58 | }, 59 | { 60 | "name": "Jonathan Wage", 61 | "email": "jonwage@gmail.com" 62 | }, 63 | { 64 | "name": "Johannes Schmitt", 65 | "email": "schmittjoh@gmail.com" 66 | } 67 | ], 68 | "description": "Docblock Annotations Parser", 69 | "homepage": "http://www.doctrine-project.org", 70 | "keywords": [ 71 | "annotations", 72 | "docblock", 73 | "parser" 74 | ], 75 | "time": "2017-07-22T11:08:38+00:00" 76 | }, 77 | { 78 | "name": "doctrine/cache", 79 | "version": "dev-master", 80 | "source": { 81 | "type": "git", 82 | "url": "https://github.com/doctrine/cache.git", 83 | "reference": "beb0fa35b61e9073f8612d9ffd34920bdaec406a" 84 | }, 85 | "dist": { 86 | "type": "zip", 87 | "url": "https://api.github.com/repos/doctrine/cache/zipball/beb0fa35b61e9073f8612d9ffd34920bdaec406a", 88 | "reference": "beb0fa35b61e9073f8612d9ffd34920bdaec406a", 89 | "shasum": "" 90 | }, 91 | "require": { 92 | "php": "~7.1" 93 | }, 94 | "conflict": { 95 | "doctrine/common": ">2.2,<2.4" 96 | }, 97 | "require-dev": { 98 | "alcaeus/mongo-php-adapter": "^1.1", 99 | "doctrine/coding-standard": "^1.0", 100 | "mongodb/mongodb": "^1.1", 101 | "phpunit/phpunit": "^6.3", 102 | "predis/predis": "~1.0", 103 | "squizlabs/php_codesniffer": "^3.0" 104 | }, 105 | "suggest": { 106 | "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" 107 | }, 108 | "type": "library", 109 | "extra": { 110 | "branch-alias": { 111 | "dev-master": "1.8.x-dev" 112 | } 113 | }, 114 | "autoload": { 115 | "psr-4": { 116 | "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" 117 | } 118 | }, 119 | "notification-url": "https://packagist.org/downloads/", 120 | "license": [ 121 | "MIT" 122 | ], 123 | "authors": [ 124 | { 125 | "name": "Roman Borschel", 126 | "email": "roman@code-factory.org" 127 | }, 128 | { 129 | "name": "Benjamin Eberlei", 130 | "email": "kontakt@beberlei.de" 131 | }, 132 | { 133 | "name": "Guilherme Blanco", 134 | "email": "guilhermeblanco@gmail.com" 135 | }, 136 | { 137 | "name": "Jonathan Wage", 138 | "email": "jonwage@gmail.com" 139 | }, 140 | { 141 | "name": "Johannes Schmitt", 142 | "email": "schmittjoh@gmail.com" 143 | } 144 | ], 145 | "description": "Caching library offering an object-oriented API for many cache backends", 146 | "homepage": "http://www.doctrine-project.org", 147 | "keywords": [ 148 | "cache", 149 | "caching" 150 | ], 151 | "time": "2017-08-25T06:51:37+00:00" 152 | }, 153 | { 154 | "name": "doctrine/lexer", 155 | "version": "dev-master", 156 | "source": { 157 | "type": "git", 158 | "url": "https://github.com/doctrine/lexer.git", 159 | "reference": "cc709ba91eee09540091ad5a5f2616727662e41b" 160 | }, 161 | "dist": { 162 | "type": "zip", 163 | "url": "https://api.github.com/repos/doctrine/lexer/zipball/cc709ba91eee09540091ad5a5f2616727662e41b", 164 | "reference": "cc709ba91eee09540091ad5a5f2616727662e41b", 165 | "shasum": "" 166 | }, 167 | "require": { 168 | "php": ">=5.3.2" 169 | }, 170 | "type": "library", 171 | "extra": { 172 | "branch-alias": { 173 | "dev-master": "1.0.x-dev" 174 | } 175 | }, 176 | "autoload": { 177 | "psr-4": { 178 | "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" 179 | } 180 | }, 181 | "notification-url": "https://packagist.org/downloads/", 182 | "license": [ 183 | "MIT" 184 | ], 185 | "authors": [ 186 | { 187 | "name": "Roman Borschel", 188 | "email": "roman@code-factory.org" 189 | }, 190 | { 191 | "name": "Guilherme Blanco", 192 | "email": "guilhermeblanco@gmail.com" 193 | }, 194 | { 195 | "name": "Johannes Schmitt", 196 | "email": "schmittjoh@gmail.com" 197 | } 198 | ], 199 | "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", 200 | "homepage": "http://www.doctrine-project.org", 201 | "keywords": [ 202 | "lexer", 203 | "parser" 204 | ], 205 | "time": "2017-07-24T09:37:08+00:00" 206 | }, 207 | { 208 | "name": "guzzlehttp/guzzle", 209 | "version": "6.3.0", 210 | "source": { 211 | "type": "git", 212 | "url": "https://github.com/guzzle/guzzle.git", 213 | "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" 214 | }, 215 | "dist": { 216 | "type": "zip", 217 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", 218 | "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", 219 | "shasum": "" 220 | }, 221 | "require": { 222 | "guzzlehttp/promises": "^1.0", 223 | "guzzlehttp/psr7": "^1.4", 224 | "php": ">=5.5" 225 | }, 226 | "require-dev": { 227 | "ext-curl": "*", 228 | "phpunit/phpunit": "^4.0 || ^5.0", 229 | "psr/log": "^1.0" 230 | }, 231 | "suggest": { 232 | "psr/log": "Required for using the Log middleware" 233 | }, 234 | "type": "library", 235 | "extra": { 236 | "branch-alias": { 237 | "dev-master": "6.2-dev" 238 | } 239 | }, 240 | "autoload": { 241 | "files": [ 242 | "src/functions_include.php" 243 | ], 244 | "psr-4": { 245 | "GuzzleHttp\\": "src/" 246 | } 247 | }, 248 | "notification-url": "https://packagist.org/downloads/", 249 | "license": [ 250 | "MIT" 251 | ], 252 | "authors": [ 253 | { 254 | "name": "Michael Dowling", 255 | "email": "mtdowling@gmail.com", 256 | "homepage": "https://github.com/mtdowling" 257 | } 258 | ], 259 | "description": "Guzzle is a PHP HTTP client library", 260 | "homepage": "http://guzzlephp.org/", 261 | "keywords": [ 262 | "client", 263 | "curl", 264 | "framework", 265 | "http", 266 | "http client", 267 | "rest", 268 | "web service" 269 | ], 270 | "time": "2017-06-22T18:50:49+00:00" 271 | }, 272 | { 273 | "name": "guzzlehttp/promises", 274 | "version": "dev-master", 275 | "source": { 276 | "type": "git", 277 | "url": "https://github.com/guzzle/promises.git", 278 | "reference": "09e549f5534380c68761260a71f847644d8f65aa" 279 | }, 280 | "dist": { 281 | "type": "zip", 282 | "url": "https://api.github.com/repos/guzzle/promises/zipball/09e549f5534380c68761260a71f847644d8f65aa", 283 | "reference": "09e549f5534380c68761260a71f847644d8f65aa", 284 | "shasum": "" 285 | }, 286 | "require": { 287 | "php": ">=5.5.0" 288 | }, 289 | "require-dev": { 290 | "phpunit/phpunit": "^4.0" 291 | }, 292 | "type": "library", 293 | "extra": { 294 | "branch-alias": { 295 | "dev-master": "1.4-dev" 296 | } 297 | }, 298 | "autoload": { 299 | "psr-4": { 300 | "GuzzleHttp\\Promise\\": "src/" 301 | }, 302 | "files": [ 303 | "src/functions_include.php" 304 | ] 305 | }, 306 | "notification-url": "https://packagist.org/downloads/", 307 | "license": [ 308 | "MIT" 309 | ], 310 | "authors": [ 311 | { 312 | "name": "Michael Dowling", 313 | "email": "mtdowling@gmail.com", 314 | "homepage": "https://github.com/mtdowling" 315 | } 316 | ], 317 | "description": "Guzzle promises library", 318 | "keywords": [ 319 | "promise" 320 | ], 321 | "time": "2017-05-20T23:14:18+00:00" 322 | }, 323 | { 324 | "name": "guzzlehttp/psr7", 325 | "version": "dev-master", 326 | "source": { 327 | "type": "git", 328 | "url": "https://github.com/guzzle/psr7.git", 329 | "reference": "811b676fbab9c99e359885032e5ebc70e442f5b8" 330 | }, 331 | "dist": { 332 | "type": "zip", 333 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/811b676fbab9c99e359885032e5ebc70e442f5b8", 334 | "reference": "811b676fbab9c99e359885032e5ebc70e442f5b8", 335 | "shasum": "" 336 | }, 337 | "require": { 338 | "php": ">=5.4.0", 339 | "psr/http-message": "~1.0" 340 | }, 341 | "provide": { 342 | "psr/http-message-implementation": "1.0" 343 | }, 344 | "require-dev": { 345 | "phpunit/phpunit": "~4.0" 346 | }, 347 | "type": "library", 348 | "extra": { 349 | "branch-alias": { 350 | "dev-master": "1.4-dev" 351 | } 352 | }, 353 | "autoload": { 354 | "psr-4": { 355 | "GuzzleHttp\\Psr7\\": "src/" 356 | }, 357 | "files": [ 358 | "src/functions_include.php" 359 | ] 360 | }, 361 | "notification-url": "https://packagist.org/downloads/", 362 | "license": [ 363 | "MIT" 364 | ], 365 | "authors": [ 366 | { 367 | "name": "Michael Dowling", 368 | "email": "mtdowling@gmail.com", 369 | "homepage": "https://github.com/mtdowling" 370 | }, 371 | { 372 | "name": "Tobias Schultze", 373 | "homepage": "https://github.com/Tobion" 374 | } 375 | ], 376 | "description": "PSR-7 message implementation that also provides common utility methods", 377 | "keywords": [ 378 | "http", 379 | "message", 380 | "request", 381 | "response", 382 | "stream", 383 | "uri", 384 | "url" 385 | ], 386 | "time": "2017-07-17T09:11:21+00:00" 387 | }, 388 | { 389 | "name": "madmis/exchange-api", 390 | "version": "0.1.3", 391 | "source": { 392 | "type": "git", 393 | "url": "https://github.com/madmis/exchange-api.git", 394 | "reference": "a65121f6846c2cf4effe9e27a0e60f6b28c888c6" 395 | }, 396 | "dist": { 397 | "type": "zip", 398 | "url": "https://api.github.com/repos/madmis/exchange-api/zipball/a65121f6846c2cf4effe9e27a0e60f6b28c888c6", 399 | "reference": "a65121f6846c2cf4effe9e27a0e60f6b28c888c6", 400 | "shasum": "" 401 | }, 402 | "require": { 403 | "guzzlehttp/guzzle": "^6.3", 404 | "guzzlehttp/psr7": "^1.4", 405 | "php": "^7.1", 406 | "symfony/property-access": "^3.3", 407 | "symfony/serializer": "^3.3" 408 | }, 409 | "require-dev": { 410 | "phpunit/phpunit": "^6.2" 411 | }, 412 | "type": "library", 413 | "autoload": { 414 | "psr-4": { 415 | "madmis\\": "src", 416 | "Test\\": "tests" 417 | } 418 | }, 419 | "notification-url": "https://packagist.org/downloads/", 420 | "license": [ 421 | "MIT" 422 | ], 423 | "description": "Common functions for cryptocurrency exchange api", 424 | "keywords": [ 425 | "api", 426 | "cryptocurrency", 427 | "exchange", 428 | "rest" 429 | ], 430 | "time": "2017-07-27T06:59:08+00:00" 431 | }, 432 | { 433 | "name": "madmis/kuna-api", 434 | "version": "dev-master", 435 | "source": { 436 | "type": "git", 437 | "url": "https://github.com/madmis/kuna-api.git", 438 | "reference": "578ea6e58406b37cafc5b05de92c42de4733848f" 439 | }, 440 | "dist": { 441 | "type": "zip", 442 | "url": "https://api.github.com/repos/madmis/kuna-api/zipball/578ea6e58406b37cafc5b05de92c42de4733848f", 443 | "reference": "578ea6e58406b37cafc5b05de92c42de4733848f", 444 | "shasum": "" 445 | }, 446 | "require": { 447 | "doctrine/annotations": "^1.4", 448 | "madmis/exchange-api": "^0.1", 449 | "php": "^7.1", 450 | "symfony/options-resolver": "^3.3" 451 | }, 452 | "require-dev": { 453 | "phpunit/phpunit": "^6.2", 454 | "symfony/console": "^3.3" 455 | }, 456 | "type": "library", 457 | "autoload": { 458 | "psr-4": { 459 | "madmis\\": "src" 460 | } 461 | }, 462 | "notification-url": "https://packagist.org/downloads/", 463 | "license": [ 464 | "MIT" 465 | ], 466 | "description": "Kuna.io REST API php client", 467 | "keywords": [ 468 | "api", 469 | "kuna", 470 | "kuna.io", 471 | "rest" 472 | ], 473 | "time": "2017-08-11T04:48:41+00:00" 474 | }, 475 | { 476 | "name": "monolog/monolog", 477 | "version": "dev-master", 478 | "source": { 479 | "type": "git", 480 | "url": "https://github.com/Seldaek/monolog.git", 481 | "reference": "7b992836275e09ed63c63fe33ca9993e515e6c5d" 482 | }, 483 | "dist": { 484 | "type": "zip", 485 | "url": "https://api.github.com/repos/Seldaek/monolog/zipball/7b992836275e09ed63c63fe33ca9993e515e6c5d", 486 | "reference": "7b992836275e09ed63c63fe33ca9993e515e6c5d", 487 | "shasum": "" 488 | }, 489 | "require": { 490 | "php": "^7.0", 491 | "psr/log": "^1.0.1" 492 | }, 493 | "provide": { 494 | "psr/log-implementation": "1.0.0" 495 | }, 496 | "require-dev": { 497 | "aws/aws-sdk-php": "^2.4.9 || ^3.0", 498 | "doctrine/couchdb": "~1.0@dev", 499 | "graylog2/gelf-php": "^1.4.2", 500 | "jakub-onderka/php-parallel-lint": "^0.9", 501 | "php-amqplib/php-amqplib": "~2.4", 502 | "php-console/php-console": "^3.1.3", 503 | "phpspec/prophecy": "^1.6.1", 504 | "phpunit/phpunit": "^5.7", 505 | "predis/predis": "^1.1", 506 | "ruflin/elastica": ">=0.90 <3.0", 507 | "sentry/sentry": "^0.13", 508 | "swiftmailer/swiftmailer": "^5.3|^6.0" 509 | }, 510 | "suggest": { 511 | "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", 512 | "doctrine/couchdb": "Allow sending log messages to a CouchDB server", 513 | "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", 514 | "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", 515 | "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", 516 | "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", 517 | "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", 518 | "php-console/php-console": "Allow sending log messages to Google Chrome", 519 | "rollbar/rollbar": "Allow sending log messages to Rollbar", 520 | "ruflin/elastica": "Allow sending log messages to an Elastic Search server", 521 | "sentry/sentry": "Allow sending log messages to a Sentry server" 522 | }, 523 | "type": "library", 524 | "extra": { 525 | "branch-alias": { 526 | "dev-master": "2.0.x-dev" 527 | } 528 | }, 529 | "autoload": { 530 | "psr-4": { 531 | "Monolog\\": "src/Monolog" 532 | } 533 | }, 534 | "notification-url": "https://packagist.org/downloads/", 535 | "license": [ 536 | "MIT" 537 | ], 538 | "authors": [ 539 | { 540 | "name": "Jordi Boggiano", 541 | "email": "j.boggiano@seld.be", 542 | "homepage": "http://seld.be" 543 | } 544 | ], 545 | "description": "Sends your logs to files, sockets, inboxes, databases and various web services", 546 | "homepage": "http://github.com/Seldaek/monolog", 547 | "keywords": [ 548 | "log", 549 | "logging", 550 | "psr-3" 551 | ], 552 | "time": "2017-06-19T10:29:40+00:00" 553 | }, 554 | { 555 | "name": "paragonie/random_compat", 556 | "version": "v2.0.10", 557 | "source": { 558 | "type": "git", 559 | "url": "https://github.com/paragonie/random_compat.git", 560 | "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d" 561 | }, 562 | "dist": { 563 | "type": "zip", 564 | "url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d", 565 | "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d", 566 | "shasum": "" 567 | }, 568 | "require": { 569 | "php": ">=5.2.0" 570 | }, 571 | "require-dev": { 572 | "phpunit/phpunit": "4.*|5.*" 573 | }, 574 | "suggest": { 575 | "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." 576 | }, 577 | "type": "library", 578 | "autoload": { 579 | "files": [ 580 | "lib/random.php" 581 | ] 582 | }, 583 | "notification-url": "https://packagist.org/downloads/", 584 | "license": [ 585 | "MIT" 586 | ], 587 | "authors": [ 588 | { 589 | "name": "Paragon Initiative Enterprises", 590 | "email": "security@paragonie.com", 591 | "homepage": "https://paragonie.com" 592 | } 593 | ], 594 | "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", 595 | "keywords": [ 596 | "csprng", 597 | "pseudorandom", 598 | "random" 599 | ], 600 | "time": "2017-03-13T16:27:32+00:00" 601 | }, 602 | { 603 | "name": "psr/cache", 604 | "version": "dev-master", 605 | "source": { 606 | "type": "git", 607 | "url": "https://github.com/php-fig/cache.git", 608 | "reference": "78c5a01ddbf11cf731f1338a4f5aba23b14d5b47" 609 | }, 610 | "dist": { 611 | "type": "zip", 612 | "url": "https://api.github.com/repos/php-fig/cache/zipball/78c5a01ddbf11cf731f1338a4f5aba23b14d5b47", 613 | "reference": "78c5a01ddbf11cf731f1338a4f5aba23b14d5b47", 614 | "shasum": "" 615 | }, 616 | "require": { 617 | "php": ">=5.3.0" 618 | }, 619 | "type": "library", 620 | "extra": { 621 | "branch-alias": { 622 | "dev-master": "1.0.x-dev" 623 | } 624 | }, 625 | "autoload": { 626 | "psr-4": { 627 | "Psr\\Cache\\": "src/" 628 | } 629 | }, 630 | "notification-url": "https://packagist.org/downloads/", 631 | "license": [ 632 | "MIT" 633 | ], 634 | "authors": [ 635 | { 636 | "name": "PHP-FIG", 637 | "homepage": "http://www.php-fig.org/" 638 | } 639 | ], 640 | "description": "Common interface for caching libraries", 641 | "keywords": [ 642 | "cache", 643 | "psr", 644 | "psr-6" 645 | ], 646 | "time": "2016-10-13T14:48:10+00:00" 647 | }, 648 | { 649 | "name": "psr/container", 650 | "version": "dev-master", 651 | "source": { 652 | "type": "git", 653 | "url": "https://github.com/php-fig/container.git", 654 | "reference": "2cc4a01788191489dc7459446ba832fa79a216a7" 655 | }, 656 | "dist": { 657 | "type": "zip", 658 | "url": "https://api.github.com/repos/php-fig/container/zipball/2cc4a01788191489dc7459446ba832fa79a216a7", 659 | "reference": "2cc4a01788191489dc7459446ba832fa79a216a7", 660 | "shasum": "" 661 | }, 662 | "require": { 663 | "php": ">=5.3.0" 664 | }, 665 | "type": "library", 666 | "extra": { 667 | "branch-alias": { 668 | "dev-master": "1.0.x-dev" 669 | } 670 | }, 671 | "autoload": { 672 | "psr-4": { 673 | "Psr\\Container\\": "src/" 674 | } 675 | }, 676 | "notification-url": "https://packagist.org/downloads/", 677 | "license": [ 678 | "MIT" 679 | ], 680 | "authors": [ 681 | { 682 | "name": "PHP-FIG", 683 | "homepage": "http://www.php-fig.org/" 684 | } 685 | ], 686 | "description": "Common Container Interface (PHP FIG PSR-11)", 687 | "homepage": "https://github.com/php-fig/container", 688 | "keywords": [ 689 | "PSR-11", 690 | "container", 691 | "container-interface", 692 | "container-interop", 693 | "psr" 694 | ], 695 | "time": "2017-06-28T15:35:32+00:00" 696 | }, 697 | { 698 | "name": "psr/http-message", 699 | "version": "dev-master", 700 | "source": { 701 | "type": "git", 702 | "url": "https://github.com/php-fig/http-message.git", 703 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" 704 | }, 705 | "dist": { 706 | "type": "zip", 707 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", 708 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", 709 | "shasum": "" 710 | }, 711 | "require": { 712 | "php": ">=5.3.0" 713 | }, 714 | "type": "library", 715 | "extra": { 716 | "branch-alias": { 717 | "dev-master": "1.0.x-dev" 718 | } 719 | }, 720 | "autoload": { 721 | "psr-4": { 722 | "Psr\\Http\\Message\\": "src/" 723 | } 724 | }, 725 | "notification-url": "https://packagist.org/downloads/", 726 | "license": [ 727 | "MIT" 728 | ], 729 | "authors": [ 730 | { 731 | "name": "PHP-FIG", 732 | "homepage": "http://www.php-fig.org/" 733 | } 734 | ], 735 | "description": "Common interface for HTTP messages", 736 | "homepage": "https://github.com/php-fig/http-message", 737 | "keywords": [ 738 | "http", 739 | "http-message", 740 | "psr", 741 | "psr-7", 742 | "request", 743 | "response" 744 | ], 745 | "time": "2016-08-06T14:39:51+00:00" 746 | }, 747 | { 748 | "name": "psr/log", 749 | "version": "dev-master", 750 | "source": { 751 | "type": "git", 752 | "url": "https://github.com/php-fig/log.git", 753 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" 754 | }, 755 | "dist": { 756 | "type": "zip", 757 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 758 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 759 | "shasum": "" 760 | }, 761 | "require": { 762 | "php": ">=5.3.0" 763 | }, 764 | "type": "library", 765 | "extra": { 766 | "branch-alias": { 767 | "dev-master": "1.0.x-dev" 768 | } 769 | }, 770 | "autoload": { 771 | "psr-4": { 772 | "Psr\\Log\\": "Psr/Log/" 773 | } 774 | }, 775 | "notification-url": "https://packagist.org/downloads/", 776 | "license": [ 777 | "MIT" 778 | ], 779 | "authors": [ 780 | { 781 | "name": "PHP-FIG", 782 | "homepage": "http://www.php-fig.org/" 783 | } 784 | ], 785 | "description": "Common interface for logging libraries", 786 | "homepage": "https://github.com/php-fig/log", 787 | "keywords": [ 788 | "log", 789 | "psr", 790 | "psr-3" 791 | ], 792 | "time": "2016-10-10T12:19:37+00:00" 793 | }, 794 | { 795 | "name": "psr/simple-cache", 796 | "version": "dev-master", 797 | "source": { 798 | "type": "git", 799 | "url": "https://github.com/php-fig/simple-cache.git", 800 | "reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24" 801 | }, 802 | "dist": { 803 | "type": "zip", 804 | "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/753fa598e8f3b9966c886fe13f370baa45ef0e24", 805 | "reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24", 806 | "shasum": "" 807 | }, 808 | "require": { 809 | "php": ">=5.3.0" 810 | }, 811 | "type": "library", 812 | "extra": { 813 | "branch-alias": { 814 | "dev-master": "1.0.x-dev" 815 | } 816 | }, 817 | "autoload": { 818 | "psr-4": { 819 | "Psr\\SimpleCache\\": "src/" 820 | } 821 | }, 822 | "notification-url": "https://packagist.org/downloads/", 823 | "license": [ 824 | "MIT" 825 | ], 826 | "authors": [ 827 | { 828 | "name": "PHP-FIG", 829 | "homepage": "http://www.php-fig.org/" 830 | } 831 | ], 832 | "description": "Common interfaces for simple caching", 833 | "keywords": [ 834 | "cache", 835 | "caching", 836 | "psr", 837 | "psr-16", 838 | "simple-cache" 839 | ], 840 | "time": "2017-01-02T13:31:39+00:00" 841 | }, 842 | { 843 | "name": "symfony/cache", 844 | "version": "dev-master", 845 | "source": { 846 | "type": "git", 847 | "url": "https://github.com/symfony/cache.git", 848 | "reference": "1c4ffc32a953f808ea117cce0fc35fe7f4af7179" 849 | }, 850 | "dist": { 851 | "type": "zip", 852 | "url": "https://api.github.com/repos/symfony/cache/zipball/1c4ffc32a953f808ea117cce0fc35fe7f4af7179", 853 | "reference": "1c4ffc32a953f808ea117cce0fc35fe7f4af7179", 854 | "shasum": "" 855 | }, 856 | "require": { 857 | "php": "^7.1.3", 858 | "psr/cache": "~1.0", 859 | "psr/log": "~1.0", 860 | "psr/simple-cache": "^1.0" 861 | }, 862 | "conflict": { 863 | "symfony/var-dumper": "<3.4" 864 | }, 865 | "provide": { 866 | "psr/cache-implementation": "1.0", 867 | "psr/simple-cache-implementation": "1.0" 868 | }, 869 | "require-dev": { 870 | "cache/integration-tests": "dev-master", 871 | "doctrine/cache": "~1.6", 872 | "doctrine/dbal": "~2.4", 873 | "predis/predis": "~1.0" 874 | }, 875 | "type": "library", 876 | "extra": { 877 | "branch-alias": { 878 | "dev-master": "4.0-dev" 879 | } 880 | }, 881 | "autoload": { 882 | "psr-4": { 883 | "Symfony\\Component\\Cache\\": "" 884 | }, 885 | "exclude-from-classmap": [ 886 | "/Tests/" 887 | ] 888 | }, 889 | "notification-url": "https://packagist.org/downloads/", 890 | "license": [ 891 | "MIT" 892 | ], 893 | "authors": [ 894 | { 895 | "name": "Nicolas Grekas", 896 | "email": "p@tchwork.com" 897 | }, 898 | { 899 | "name": "Symfony Community", 900 | "homepage": "https://symfony.com/contributors" 901 | } 902 | ], 903 | "description": "Symfony Cache component with PSR-6, PSR-16, and tags", 904 | "homepage": "https://symfony.com", 905 | "keywords": [ 906 | "caching", 907 | "psr6" 908 | ], 909 | "time": "2017-09-06T19:16:37+00:00" 910 | }, 911 | { 912 | "name": "symfony/config", 913 | "version": "dev-master", 914 | "source": { 915 | "type": "git", 916 | "url": "https://github.com/symfony/config.git", 917 | "reference": "c5fda5f2c06573162e6614f6f6a8e19d8f97928b" 918 | }, 919 | "dist": { 920 | "type": "zip", 921 | "url": "https://api.github.com/repos/symfony/config/zipball/c5fda5f2c06573162e6614f6f6a8e19d8f97928b", 922 | "reference": "c5fda5f2c06573162e6614f6f6a8e19d8f97928b", 923 | "shasum": "" 924 | }, 925 | "require": { 926 | "php": "^7.1.3", 927 | "symfony/filesystem": "~3.4|~4.0" 928 | }, 929 | "conflict": { 930 | "symfony/dependency-injection": "<3.4", 931 | "symfony/finder": "<3.4" 932 | }, 933 | "require-dev": { 934 | "symfony/dependency-injection": "~3.4|~4.0", 935 | "symfony/finder": "~3.4|~4.0", 936 | "symfony/yaml": "~3.4|~4.0" 937 | }, 938 | "suggest": { 939 | "symfony/yaml": "To use the yaml reference dumper" 940 | }, 941 | "type": "library", 942 | "extra": { 943 | "branch-alias": { 944 | "dev-master": "4.0-dev" 945 | } 946 | }, 947 | "autoload": { 948 | "psr-4": { 949 | "Symfony\\Component\\Config\\": "" 950 | }, 951 | "exclude-from-classmap": [ 952 | "/Tests/" 953 | ] 954 | }, 955 | "notification-url": "https://packagist.org/downloads/", 956 | "license": [ 957 | "MIT" 958 | ], 959 | "authors": [ 960 | { 961 | "name": "Fabien Potencier", 962 | "email": "fabien@symfony.com" 963 | }, 964 | { 965 | "name": "Symfony Community", 966 | "homepage": "https://symfony.com/contributors" 967 | } 968 | ], 969 | "description": "Symfony Config Component", 970 | "homepage": "https://symfony.com", 971 | "time": "2017-09-04T18:13:11+00:00" 972 | }, 973 | { 974 | "name": "symfony/console", 975 | "version": "dev-master", 976 | "source": { 977 | "type": "git", 978 | "url": "https://github.com/symfony/console.git", 979 | "reference": "85a37b6e82a45c18b91100cffb8243a3b7ee6e27" 980 | }, 981 | "dist": { 982 | "type": "zip", 983 | "url": "https://api.github.com/repos/symfony/console/zipball/85a37b6e82a45c18b91100cffb8243a3b7ee6e27", 984 | "reference": "85a37b6e82a45c18b91100cffb8243a3b7ee6e27", 985 | "shasum": "" 986 | }, 987 | "require": { 988 | "php": "^7.1.3", 989 | "symfony/debug": "~3.4|~4.0", 990 | "symfony/polyfill-mbstring": "~1.0" 991 | }, 992 | "conflict": { 993 | "symfony/dependency-injection": "<3.4", 994 | "symfony/process": "<3.3" 995 | }, 996 | "require-dev": { 997 | "psr/log": "~1.0", 998 | "symfony/config": "~3.4|~4.0", 999 | "symfony/dependency-injection": "~3.4|~4.0", 1000 | "symfony/event-dispatcher": "~3.4|~4.0", 1001 | "symfony/lock": "~3.4|~4.0", 1002 | "symfony/process": "~3.4|~4.0" 1003 | }, 1004 | "suggest": { 1005 | "psr/log": "For using the console logger", 1006 | "symfony/event-dispatcher": "", 1007 | "symfony/lock": "", 1008 | "symfony/process": "" 1009 | }, 1010 | "type": "library", 1011 | "extra": { 1012 | "branch-alias": { 1013 | "dev-master": "4.0-dev" 1014 | } 1015 | }, 1016 | "autoload": { 1017 | "psr-4": { 1018 | "Symfony\\Component\\Console\\": "" 1019 | }, 1020 | "exclude-from-classmap": [ 1021 | "/Tests/" 1022 | ] 1023 | }, 1024 | "notification-url": "https://packagist.org/downloads/", 1025 | "license": [ 1026 | "MIT" 1027 | ], 1028 | "authors": [ 1029 | { 1030 | "name": "Fabien Potencier", 1031 | "email": "fabien@symfony.com" 1032 | }, 1033 | { 1034 | "name": "Symfony Community", 1035 | "homepage": "https://symfony.com/contributors" 1036 | } 1037 | ], 1038 | "description": "Symfony Console Component", 1039 | "homepage": "https://symfony.com", 1040 | "time": "2017-09-06T19:47:57+00:00" 1041 | }, 1042 | { 1043 | "name": "symfony/debug", 1044 | "version": "dev-master", 1045 | "source": { 1046 | "type": "git", 1047 | "url": "https://github.com/symfony/debug.git", 1048 | "reference": "96bc445c20a66daacb138e5f4c53bf29a4b64c9c" 1049 | }, 1050 | "dist": { 1051 | "type": "zip", 1052 | "url": "https://api.github.com/repos/symfony/debug/zipball/96bc445c20a66daacb138e5f4c53bf29a4b64c9c", 1053 | "reference": "96bc445c20a66daacb138e5f4c53bf29a4b64c9c", 1054 | "shasum": "" 1055 | }, 1056 | "require": { 1057 | "php": "^7.1.3", 1058 | "psr/log": "~1.0" 1059 | }, 1060 | "conflict": { 1061 | "symfony/http-kernel": "<3.4" 1062 | }, 1063 | "require-dev": { 1064 | "symfony/http-kernel": "~3.4|~4.0" 1065 | }, 1066 | "type": "library", 1067 | "extra": { 1068 | "branch-alias": { 1069 | "dev-master": "4.0-dev" 1070 | } 1071 | }, 1072 | "autoload": { 1073 | "psr-4": { 1074 | "Symfony\\Component\\Debug\\": "" 1075 | }, 1076 | "exclude-from-classmap": [ 1077 | "/Tests/" 1078 | ] 1079 | }, 1080 | "notification-url": "https://packagist.org/downloads/", 1081 | "license": [ 1082 | "MIT" 1083 | ], 1084 | "authors": [ 1085 | { 1086 | "name": "Fabien Potencier", 1087 | "email": "fabien@symfony.com" 1088 | }, 1089 | { 1090 | "name": "Symfony Community", 1091 | "homepage": "https://symfony.com/contributors" 1092 | } 1093 | ], 1094 | "description": "Symfony Debug Component", 1095 | "homepage": "https://symfony.com", 1096 | "time": "2017-09-03T14:49:52+00:00" 1097 | }, 1098 | { 1099 | "name": "symfony/dependency-injection", 1100 | "version": "dev-master", 1101 | "source": { 1102 | "type": "git", 1103 | "url": "https://github.com/symfony/dependency-injection.git", 1104 | "reference": "43c8019a0e4203d483b92fae3c15eb16fda55f17" 1105 | }, 1106 | "dist": { 1107 | "type": "zip", 1108 | "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/43c8019a0e4203d483b92fae3c15eb16fda55f17", 1109 | "reference": "43c8019a0e4203d483b92fae3c15eb16fda55f17", 1110 | "shasum": "" 1111 | }, 1112 | "require": { 1113 | "php": "^7.1.3", 1114 | "psr/container": "^1.0" 1115 | }, 1116 | "conflict": { 1117 | "symfony/config": "<3.4", 1118 | "symfony/finder": "<3.4", 1119 | "symfony/proxy-manager-bridge": "<3.4", 1120 | "symfony/yaml": "<3.4" 1121 | }, 1122 | "provide": { 1123 | "psr/container-implementation": "1.0" 1124 | }, 1125 | "require-dev": { 1126 | "symfony/config": "~3.4|~4.0", 1127 | "symfony/expression-language": "~3.4|~4.0", 1128 | "symfony/yaml": "~3.4|~4.0" 1129 | }, 1130 | "suggest": { 1131 | "symfony/config": "", 1132 | "symfony/expression-language": "For using expressions in service container configuration", 1133 | "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", 1134 | "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", 1135 | "symfony/yaml": "" 1136 | }, 1137 | "type": "library", 1138 | "extra": { 1139 | "branch-alias": { 1140 | "dev-master": "4.0-dev" 1141 | } 1142 | }, 1143 | "autoload": { 1144 | "psr-4": { 1145 | "Symfony\\Component\\DependencyInjection\\": "" 1146 | }, 1147 | "exclude-from-classmap": [ 1148 | "/Tests/" 1149 | ] 1150 | }, 1151 | "notification-url": "https://packagist.org/downloads/", 1152 | "license": [ 1153 | "MIT" 1154 | ], 1155 | "authors": [ 1156 | { 1157 | "name": "Fabien Potencier", 1158 | "email": "fabien@symfony.com" 1159 | }, 1160 | { 1161 | "name": "Symfony Community", 1162 | "homepage": "https://symfony.com/contributors" 1163 | } 1164 | ], 1165 | "description": "Symfony DependencyInjection Component", 1166 | "homepage": "https://symfony.com", 1167 | "time": "2017-09-04T17:33:15+00:00" 1168 | }, 1169 | { 1170 | "name": "symfony/event-dispatcher", 1171 | "version": "dev-master", 1172 | "source": { 1173 | "type": "git", 1174 | "url": "https://github.com/symfony/event-dispatcher.git", 1175 | "reference": "96440b5f3392aa7415ed720a290ceb7dcae3b00c" 1176 | }, 1177 | "dist": { 1178 | "type": "zip", 1179 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/96440b5f3392aa7415ed720a290ceb7dcae3b00c", 1180 | "reference": "96440b5f3392aa7415ed720a290ceb7dcae3b00c", 1181 | "shasum": "" 1182 | }, 1183 | "require": { 1184 | "php": "^7.1.3" 1185 | }, 1186 | "conflict": { 1187 | "symfony/dependency-injection": "<3.4" 1188 | }, 1189 | "require-dev": { 1190 | "psr/log": "~1.0", 1191 | "symfony/config": "~3.4|~4.0", 1192 | "symfony/dependency-injection": "~3.4|~4.0", 1193 | "symfony/expression-language": "~3.4|~4.0", 1194 | "symfony/stopwatch": "~3.4|~4.0" 1195 | }, 1196 | "suggest": { 1197 | "symfony/dependency-injection": "", 1198 | "symfony/http-kernel": "" 1199 | }, 1200 | "type": "library", 1201 | "extra": { 1202 | "branch-alias": { 1203 | "dev-master": "4.0-dev" 1204 | } 1205 | }, 1206 | "autoload": { 1207 | "psr-4": { 1208 | "Symfony\\Component\\EventDispatcher\\": "" 1209 | }, 1210 | "exclude-from-classmap": [ 1211 | "/Tests/" 1212 | ] 1213 | }, 1214 | "notification-url": "https://packagist.org/downloads/", 1215 | "license": [ 1216 | "MIT" 1217 | ], 1218 | "authors": [ 1219 | { 1220 | "name": "Fabien Potencier", 1221 | "email": "fabien@symfony.com" 1222 | }, 1223 | { 1224 | "name": "Symfony Community", 1225 | "homepage": "https://symfony.com/contributors" 1226 | } 1227 | ], 1228 | "description": "Symfony EventDispatcher Component", 1229 | "homepage": "https://symfony.com", 1230 | "time": "2017-06-12T18:12:26+00:00" 1231 | }, 1232 | { 1233 | "name": "symfony/filesystem", 1234 | "version": "dev-master", 1235 | "source": { 1236 | "type": "git", 1237 | "url": "https://github.com/symfony/filesystem.git", 1238 | "reference": "df8e441d071093d215272c459581b06e17e1783e" 1239 | }, 1240 | "dist": { 1241 | "type": "zip", 1242 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/df8e441d071093d215272c459581b06e17e1783e", 1243 | "reference": "df8e441d071093d215272c459581b06e17e1783e", 1244 | "shasum": "" 1245 | }, 1246 | "require": { 1247 | "php": "^7.1.3" 1248 | }, 1249 | "type": "library", 1250 | "extra": { 1251 | "branch-alias": { 1252 | "dev-master": "4.0-dev" 1253 | } 1254 | }, 1255 | "autoload": { 1256 | "psr-4": { 1257 | "Symfony\\Component\\Filesystem\\": "" 1258 | }, 1259 | "exclude-from-classmap": [ 1260 | "/Tests/" 1261 | ] 1262 | }, 1263 | "notification-url": "https://packagist.org/downloads/", 1264 | "license": [ 1265 | "MIT" 1266 | ], 1267 | "authors": [ 1268 | { 1269 | "name": "Fabien Potencier", 1270 | "email": "fabien@symfony.com" 1271 | }, 1272 | { 1273 | "name": "Symfony Community", 1274 | "homepage": "https://symfony.com/contributors" 1275 | } 1276 | ], 1277 | "description": "Symfony Filesystem Component", 1278 | "homepage": "https://symfony.com", 1279 | "time": "2017-08-02T05:32:45+00:00" 1280 | }, 1281 | { 1282 | "name": "symfony/finder", 1283 | "version": "dev-master", 1284 | "source": { 1285 | "type": "git", 1286 | "url": "https://github.com/symfony/finder.git", 1287 | "reference": "d04fb01c1aa6e3f2f62e5505b62ede74f7cd4d1a" 1288 | }, 1289 | "dist": { 1290 | "type": "zip", 1291 | "url": "https://api.github.com/repos/symfony/finder/zipball/d04fb01c1aa6e3f2f62e5505b62ede74f7cd4d1a", 1292 | "reference": "d04fb01c1aa6e3f2f62e5505b62ede74f7cd4d1a", 1293 | "shasum": "" 1294 | }, 1295 | "require": { 1296 | "php": "^7.1.3" 1297 | }, 1298 | "type": "library", 1299 | "extra": { 1300 | "branch-alias": { 1301 | "dev-master": "4.0-dev" 1302 | } 1303 | }, 1304 | "autoload": { 1305 | "psr-4": { 1306 | "Symfony\\Component\\Finder\\": "" 1307 | }, 1308 | "exclude-from-classmap": [ 1309 | "/Tests/" 1310 | ] 1311 | }, 1312 | "notification-url": "https://packagist.org/downloads/", 1313 | "license": [ 1314 | "MIT" 1315 | ], 1316 | "authors": [ 1317 | { 1318 | "name": "Fabien Potencier", 1319 | "email": "fabien@symfony.com" 1320 | }, 1321 | { 1322 | "name": "Symfony Community", 1323 | "homepage": "https://symfony.com/contributors" 1324 | } 1325 | ], 1326 | "description": "Symfony Finder Component", 1327 | "homepage": "https://symfony.com", 1328 | "time": "2017-06-01T22:17:54+00:00" 1329 | }, 1330 | { 1331 | "name": "symfony/flex", 1332 | "version": "dev-master", 1333 | "source": { 1334 | "type": "git", 1335 | "url": "https://github.com/symfony/flex.git", 1336 | "reference": "6cfb2e6f690d905843cc52ea3236eb54ba50a42e" 1337 | }, 1338 | "dist": { 1339 | "type": "zip", 1340 | "url": "https://api.github.com/repos/symfony/flex/zipball/6cfb2e6f690d905843cc52ea3236eb54ba50a42e", 1341 | "reference": "6cfb2e6f690d905843cc52ea3236eb54ba50a42e", 1342 | "shasum": "" 1343 | }, 1344 | "require": { 1345 | "composer-plugin-api": "^1.1", 1346 | "php": "^7.1" 1347 | }, 1348 | "require-dev": { 1349 | "composer/composer": "^1.4", 1350 | "symfony/phpunit-bridge": "^3.2.8" 1351 | }, 1352 | "type": "composer-plugin", 1353 | "extra": { 1354 | "branch-alias": { 1355 | "dev-master": "1.0-dev" 1356 | }, 1357 | "class": "Symfony\\Flex\\Flex" 1358 | }, 1359 | "autoload": { 1360 | "psr-4": { 1361 | "Symfony\\Flex\\": "src" 1362 | } 1363 | }, 1364 | "notification-url": "https://packagist.org/downloads/", 1365 | "license": [ 1366 | "MIT" 1367 | ], 1368 | "authors": [ 1369 | { 1370 | "name": "Fabien Potencier", 1371 | "email": "fabien.potencier@gmail.com" 1372 | } 1373 | ], 1374 | "time": "2017-09-01T23:43:15+00:00" 1375 | }, 1376 | { 1377 | "name": "symfony/framework-bundle", 1378 | "version": "dev-master", 1379 | "source": { 1380 | "type": "git", 1381 | "url": "https://github.com/symfony/framework-bundle.git", 1382 | "reference": "d4010f9f517220df37a1a639b85bf88d2f1c6b40" 1383 | }, 1384 | "dist": { 1385 | "type": "zip", 1386 | "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/d4010f9f517220df37a1a639b85bf88d2f1c6b40", 1387 | "reference": "d4010f9f517220df37a1a639b85bf88d2f1c6b40", 1388 | "shasum": "" 1389 | }, 1390 | "require": { 1391 | "ext-xml": "*", 1392 | "php": "^7.1.3", 1393 | "symfony/cache": "~3.4|~4.0", 1394 | "symfony/config": "~3.4|~4.0", 1395 | "symfony/dependency-injection": "~3.4|~4.0", 1396 | "symfony/event-dispatcher": "~3.4|~4.0", 1397 | "symfony/filesystem": "~3.4|~4.0", 1398 | "symfony/finder": "~3.4|~4.0", 1399 | "symfony/http-foundation": "~3.4|~4.0", 1400 | "symfony/http-kernel": "~3.4|~4.0", 1401 | "symfony/polyfill-mbstring": "~1.0", 1402 | "symfony/routing": "~3.4|~4.0" 1403 | }, 1404 | "conflict": { 1405 | "phpdocumentor/reflection-docblock": "<3.0", 1406 | "phpdocumentor/type-resolver": "<0.2.0", 1407 | "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", 1408 | "symfony/asset": "<3.4", 1409 | "symfony/console": "<3.4", 1410 | "symfony/form": "<3.4", 1411 | "symfony/property-info": "<3.4", 1412 | "symfony/serializer": "<3.4", 1413 | "symfony/translation": "<3.4", 1414 | "symfony/validator": "<3.4", 1415 | "symfony/workflow": "<3.4" 1416 | }, 1417 | "require-dev": { 1418 | "doctrine/annotations": "~1.0", 1419 | "doctrine/cache": "~1.0", 1420 | "fig/link-util": "^1.0", 1421 | "phpdocumentor/reflection-docblock": "^3.0|^4.0", 1422 | "symfony/asset": "~3.4|~4.0", 1423 | "symfony/browser-kit": "~3.4|~4.0", 1424 | "symfony/console": "~3.4|~4.0", 1425 | "symfony/css-selector": "~3.4|~4.0", 1426 | "symfony/dom-crawler": "~3.4|~4.0", 1427 | "symfony/expression-language": "~3.4|~4.0", 1428 | "symfony/form": "~3.4|~4.0", 1429 | "symfony/polyfill-intl-icu": "~1.0", 1430 | "symfony/process": "~3.4|~4.0", 1431 | "symfony/property-info": "~3.4|~4.0", 1432 | "symfony/security": "~3.4|~4.0", 1433 | "symfony/security-core": "~3.4|~4.0", 1434 | "symfony/security-csrf": "~3.4|~4.0", 1435 | "symfony/serializer": "~3.4|~4.0", 1436 | "symfony/stopwatch": "~3.4|~4.0", 1437 | "symfony/templating": "~3.4|~4.0", 1438 | "symfony/translation": "~3.4|~4.0", 1439 | "symfony/validator": "~3.4|~4.0", 1440 | "symfony/var-dumper": "~3.4|~4.0", 1441 | "symfony/web-link": "~3.4|~4.0", 1442 | "symfony/workflow": "~3.4|~4.0", 1443 | "symfony/yaml": "~3.4|~4.0", 1444 | "twig/twig": "~1.34|~2.4" 1445 | }, 1446 | "suggest": { 1447 | "ext-apcu": "For best performance of the system caches", 1448 | "symfony/console": "For using the console commands", 1449 | "symfony/form": "For using forms", 1450 | "symfony/property-info": "For using the property_info service", 1451 | "symfony/serializer": "For using the serializer service", 1452 | "symfony/validator": "For using validation", 1453 | "symfony/web-link": "For using web links, features such as preloading, prefetching or prerendering", 1454 | "symfony/yaml": "For using the debug:config and lint:yaml commands" 1455 | }, 1456 | "type": "symfony-bundle", 1457 | "extra": { 1458 | "branch-alias": { 1459 | "dev-master": "4.0-dev" 1460 | } 1461 | }, 1462 | "autoload": { 1463 | "psr-4": { 1464 | "Symfony\\Bundle\\FrameworkBundle\\": "" 1465 | }, 1466 | "exclude-from-classmap": [ 1467 | "/Tests/" 1468 | ] 1469 | }, 1470 | "notification-url": "https://packagist.org/downloads/", 1471 | "license": [ 1472 | "MIT" 1473 | ], 1474 | "authors": [ 1475 | { 1476 | "name": "Fabien Potencier", 1477 | "email": "fabien@symfony.com" 1478 | }, 1479 | { 1480 | "name": "Symfony Community", 1481 | "homepage": "https://symfony.com/contributors" 1482 | } 1483 | ], 1484 | "description": "Symfony FrameworkBundle", 1485 | "homepage": "https://symfony.com", 1486 | "time": "2017-09-06T19:16:37+00:00" 1487 | }, 1488 | { 1489 | "name": "symfony/http-foundation", 1490 | "version": "dev-master", 1491 | "source": { 1492 | "type": "git", 1493 | "url": "https://github.com/symfony/http-foundation.git", 1494 | "reference": "66e6b80fff6601249bc15f29ff2b70c5e8d54119" 1495 | }, 1496 | "dist": { 1497 | "type": "zip", 1498 | "url": "https://api.github.com/repos/symfony/http-foundation/zipball/66e6b80fff6601249bc15f29ff2b70c5e8d54119", 1499 | "reference": "66e6b80fff6601249bc15f29ff2b70c5e8d54119", 1500 | "shasum": "" 1501 | }, 1502 | "require": { 1503 | "php": "^7.1.3", 1504 | "symfony/polyfill-mbstring": "~1.1" 1505 | }, 1506 | "require-dev": { 1507 | "symfony/expression-language": "~3.4|~4.0" 1508 | }, 1509 | "type": "library", 1510 | "extra": { 1511 | "branch-alias": { 1512 | "dev-master": "4.0-dev" 1513 | } 1514 | }, 1515 | "autoload": { 1516 | "psr-4": { 1517 | "Symfony\\Component\\HttpFoundation\\": "" 1518 | }, 1519 | "exclude-from-classmap": [ 1520 | "/Tests/" 1521 | ] 1522 | }, 1523 | "notification-url": "https://packagist.org/downloads/", 1524 | "license": [ 1525 | "MIT" 1526 | ], 1527 | "authors": [ 1528 | { 1529 | "name": "Fabien Potencier", 1530 | "email": "fabien@symfony.com" 1531 | }, 1532 | { 1533 | "name": "Symfony Community", 1534 | "homepage": "https://symfony.com/contributors" 1535 | } 1536 | ], 1537 | "description": "Symfony HttpFoundation Component", 1538 | "homepage": "https://symfony.com", 1539 | "time": "2017-09-06T19:16:37+00:00" 1540 | }, 1541 | { 1542 | "name": "symfony/http-kernel", 1543 | "version": "dev-master", 1544 | "source": { 1545 | "type": "git", 1546 | "url": "https://github.com/symfony/http-kernel.git", 1547 | "reference": "b476f683423474d0afe502331558b5f5dae655dd" 1548 | }, 1549 | "dist": { 1550 | "type": "zip", 1551 | "url": "https://api.github.com/repos/symfony/http-kernel/zipball/b476f683423474d0afe502331558b5f5dae655dd", 1552 | "reference": "b476f683423474d0afe502331558b5f5dae655dd", 1553 | "shasum": "" 1554 | }, 1555 | "require": { 1556 | "php": "^7.1.3", 1557 | "psr/log": "~1.0", 1558 | "symfony/debug": "~3.4|~4.0", 1559 | "symfony/event-dispatcher": "~3.4|~4.0", 1560 | "symfony/http-foundation": "~3.4|~4.0" 1561 | }, 1562 | "conflict": { 1563 | "symfony/config": "<3.4", 1564 | "symfony/dependency-injection": "<3.4", 1565 | "symfony/var-dumper": "<3.4", 1566 | "twig/twig": "<1.34|<2.4,>=2" 1567 | }, 1568 | "require-dev": { 1569 | "psr/cache": "~1.0", 1570 | "symfony/browser-kit": "~3.4|~4.0", 1571 | "symfony/class-loader": "~3.4|~4.0", 1572 | "symfony/config": "~3.4|~4.0", 1573 | "symfony/console": "~3.4|~4.0", 1574 | "symfony/css-selector": "~3.4|~4.0", 1575 | "symfony/dependency-injection": "~3.4|~4.0", 1576 | "symfony/dom-crawler": "~3.4|~4.0", 1577 | "symfony/expression-language": "~3.4|~4.0", 1578 | "symfony/process": "~3.4|~4.0", 1579 | "symfony/routing": "~3.4|~4.0", 1580 | "symfony/stopwatch": "~3.4|~4.0", 1581 | "symfony/templating": "~3.4|~4.0", 1582 | "symfony/translation": "~3.4|~4.0", 1583 | "symfony/var-dumper": "~3.4|~4.0" 1584 | }, 1585 | "suggest": { 1586 | "symfony/browser-kit": "", 1587 | "symfony/config": "", 1588 | "symfony/console": "", 1589 | "symfony/dependency-injection": "", 1590 | "symfony/var-dumper": "" 1591 | }, 1592 | "type": "library", 1593 | "extra": { 1594 | "branch-alias": { 1595 | "dev-master": "4.0-dev" 1596 | } 1597 | }, 1598 | "autoload": { 1599 | "psr-4": { 1600 | "Symfony\\Component\\HttpKernel\\": "" 1601 | }, 1602 | "exclude-from-classmap": [ 1603 | "/Tests/" 1604 | ] 1605 | }, 1606 | "notification-url": "https://packagist.org/downloads/", 1607 | "license": [ 1608 | "MIT" 1609 | ], 1610 | "authors": [ 1611 | { 1612 | "name": "Fabien Potencier", 1613 | "email": "fabien@symfony.com" 1614 | }, 1615 | { 1616 | "name": "Symfony Community", 1617 | "homepage": "https://symfony.com/contributors" 1618 | } 1619 | ], 1620 | "description": "Symfony HttpKernel Component", 1621 | "homepage": "https://symfony.com", 1622 | "time": "2017-09-05T07:06:08+00:00" 1623 | }, 1624 | { 1625 | "name": "symfony/inflector", 1626 | "version": "dev-master", 1627 | "source": { 1628 | "type": "git", 1629 | "url": "https://github.com/symfony/inflector.git", 1630 | "reference": "8740990f67ec9f89bfa116d11bad2990dd510ece" 1631 | }, 1632 | "dist": { 1633 | "type": "zip", 1634 | "url": "https://api.github.com/repos/symfony/inflector/zipball/8740990f67ec9f89bfa116d11bad2990dd510ece", 1635 | "reference": "8740990f67ec9f89bfa116d11bad2990dd510ece", 1636 | "shasum": "" 1637 | }, 1638 | "require": { 1639 | "php": "^7.1.3" 1640 | }, 1641 | "type": "library", 1642 | "extra": { 1643 | "branch-alias": { 1644 | "dev-master": "4.0-dev" 1645 | } 1646 | }, 1647 | "autoload": { 1648 | "psr-4": { 1649 | "Symfony\\Component\\Inflector\\": "" 1650 | }, 1651 | "exclude-from-classmap": [ 1652 | "/Tests/" 1653 | ] 1654 | }, 1655 | "notification-url": "https://packagist.org/downloads/", 1656 | "license": [ 1657 | "MIT" 1658 | ], 1659 | "authors": [ 1660 | { 1661 | "name": "Bernhard Schussek", 1662 | "email": "bschussek@gmail.com" 1663 | }, 1664 | { 1665 | "name": "Symfony Community", 1666 | "homepage": "https://symfony.com/contributors" 1667 | } 1668 | ], 1669 | "description": "Symfony Inflector Component", 1670 | "homepage": "https://symfony.com", 1671 | "keywords": [ 1672 | "inflection", 1673 | "pluralize", 1674 | "singularize", 1675 | "string", 1676 | "symfony", 1677 | "words" 1678 | ], 1679 | "time": "2017-08-31T20:46:21+00:00" 1680 | }, 1681 | { 1682 | "name": "symfony/options-resolver", 1683 | "version": "v3.3.0", 1684 | "source": { 1685 | "type": "git", 1686 | "url": "https://github.com/symfony/options-resolver.git", 1687 | "reference": "ff48982d295bcac1fd861f934f041ebc73ae40f0" 1688 | }, 1689 | "dist": { 1690 | "type": "zip", 1691 | "url": "https://api.github.com/repos/symfony/options-resolver/zipball/ff48982d295bcac1fd861f934f041ebc73ae40f0", 1692 | "reference": "ff48982d295bcac1fd861f934f041ebc73ae40f0", 1693 | "shasum": "" 1694 | }, 1695 | "require": { 1696 | "php": ">=5.5.9" 1697 | }, 1698 | "type": "library", 1699 | "extra": { 1700 | "branch-alias": { 1701 | "dev-master": "3.3-dev" 1702 | } 1703 | }, 1704 | "autoload": { 1705 | "psr-4": { 1706 | "Symfony\\Component\\OptionsResolver\\": "" 1707 | }, 1708 | "exclude-from-classmap": [ 1709 | "/Tests/" 1710 | ] 1711 | }, 1712 | "notification-url": "https://packagist.org/downloads/", 1713 | "license": [ 1714 | "MIT" 1715 | ], 1716 | "authors": [ 1717 | { 1718 | "name": "Fabien Potencier", 1719 | "email": "fabien@symfony.com" 1720 | }, 1721 | { 1722 | "name": "Symfony Community", 1723 | "homepage": "https://symfony.com/contributors" 1724 | } 1725 | ], 1726 | "description": "Symfony OptionsResolver Component", 1727 | "homepage": "https://symfony.com", 1728 | "keywords": [ 1729 | "config", 1730 | "configuration", 1731 | "options" 1732 | ], 1733 | "time": "2017-04-12T14:14:56+00:00" 1734 | }, 1735 | { 1736 | "name": "symfony/polyfill-mbstring", 1737 | "version": "dev-master", 1738 | "source": { 1739 | "type": "git", 1740 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1741 | "reference": "7c8fae0ac1d216eb54349e6a8baa57d515fe8803" 1742 | }, 1743 | "dist": { 1744 | "type": "zip", 1745 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7c8fae0ac1d216eb54349e6a8baa57d515fe8803", 1746 | "reference": "7c8fae0ac1d216eb54349e6a8baa57d515fe8803", 1747 | "shasum": "" 1748 | }, 1749 | "require": { 1750 | "php": ">=5.3.3" 1751 | }, 1752 | "suggest": { 1753 | "ext-mbstring": "For best performance" 1754 | }, 1755 | "type": "library", 1756 | "extra": { 1757 | "branch-alias": { 1758 | "dev-master": "1.5-dev" 1759 | } 1760 | }, 1761 | "autoload": { 1762 | "psr-4": { 1763 | "Symfony\\Polyfill\\Mbstring\\": "" 1764 | }, 1765 | "files": [ 1766 | "bootstrap.php" 1767 | ] 1768 | }, 1769 | "notification-url": "https://packagist.org/downloads/", 1770 | "license": [ 1771 | "MIT" 1772 | ], 1773 | "authors": [ 1774 | { 1775 | "name": "Nicolas Grekas", 1776 | "email": "p@tchwork.com" 1777 | }, 1778 | { 1779 | "name": "Symfony Community", 1780 | "homepage": "https://symfony.com/contributors" 1781 | } 1782 | ], 1783 | "description": "Symfony polyfill for the Mbstring extension", 1784 | "homepage": "https://symfony.com", 1785 | "keywords": [ 1786 | "compatibility", 1787 | "mbstring", 1788 | "polyfill", 1789 | "portable", 1790 | "shim" 1791 | ], 1792 | "time": "2017-06-14T15:44:48+00:00" 1793 | }, 1794 | { 1795 | "name": "symfony/polyfill-php70", 1796 | "version": "dev-master", 1797 | "source": { 1798 | "type": "git", 1799 | "url": "https://github.com/symfony/polyfill-php70.git", 1800 | "reference": "b6482e68974486984f59449ecea1fbbb22ff840f" 1801 | }, 1802 | "dist": { 1803 | "type": "zip", 1804 | "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/b6482e68974486984f59449ecea1fbbb22ff840f", 1805 | "reference": "b6482e68974486984f59449ecea1fbbb22ff840f", 1806 | "shasum": "" 1807 | }, 1808 | "require": { 1809 | "paragonie/random_compat": "~1.0|~2.0", 1810 | "php": ">=5.3.3" 1811 | }, 1812 | "type": "library", 1813 | "extra": { 1814 | "branch-alias": { 1815 | "dev-master": "1.5-dev" 1816 | } 1817 | }, 1818 | "autoload": { 1819 | "psr-4": { 1820 | "Symfony\\Polyfill\\Php70\\": "" 1821 | }, 1822 | "files": [ 1823 | "bootstrap.php" 1824 | ], 1825 | "classmap": [ 1826 | "Resources/stubs" 1827 | ] 1828 | }, 1829 | "notification-url": "https://packagist.org/downloads/", 1830 | "license": [ 1831 | "MIT" 1832 | ], 1833 | "authors": [ 1834 | { 1835 | "name": "Nicolas Grekas", 1836 | "email": "p@tchwork.com" 1837 | }, 1838 | { 1839 | "name": "Symfony Community", 1840 | "homepage": "https://symfony.com/contributors" 1841 | } 1842 | ], 1843 | "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", 1844 | "homepage": "https://symfony.com", 1845 | "keywords": [ 1846 | "compatibility", 1847 | "polyfill", 1848 | "portable", 1849 | "shim" 1850 | ], 1851 | "time": "2017-06-14T15:44:48+00:00" 1852 | }, 1853 | { 1854 | "name": "symfony/polyfill-php72", 1855 | "version": "dev-master", 1856 | "source": { 1857 | "type": "git", 1858 | "url": "https://github.com/symfony/polyfill-php72.git", 1859 | "reference": "8abc9097f5001d310f0edba727469c988acc6ea7" 1860 | }, 1861 | "dist": { 1862 | "type": "zip", 1863 | "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/8abc9097f5001d310f0edba727469c988acc6ea7", 1864 | "reference": "8abc9097f5001d310f0edba727469c988acc6ea7", 1865 | "shasum": "" 1866 | }, 1867 | "require": { 1868 | "php": ">=5.3.3" 1869 | }, 1870 | "type": "library", 1871 | "extra": { 1872 | "branch-alias": { 1873 | "dev-master": "1.5-dev" 1874 | } 1875 | }, 1876 | "autoload": { 1877 | "psr-4": { 1878 | "Symfony\\Polyfill\\Php72\\": "" 1879 | }, 1880 | "files": [ 1881 | "bootstrap.php" 1882 | ] 1883 | }, 1884 | "notification-url": "https://packagist.org/downloads/", 1885 | "license": [ 1886 | "MIT" 1887 | ], 1888 | "authors": [ 1889 | { 1890 | "name": "Nicolas Grekas", 1891 | "email": "p@tchwork.com" 1892 | }, 1893 | { 1894 | "name": "Symfony Community", 1895 | "homepage": "https://symfony.com/contributors" 1896 | } 1897 | ], 1898 | "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", 1899 | "homepage": "https://symfony.com", 1900 | "keywords": [ 1901 | "compatibility", 1902 | "polyfill", 1903 | "portable", 1904 | "shim" 1905 | ], 1906 | "time": "2017-07-11T13:25:55+00:00" 1907 | }, 1908 | { 1909 | "name": "symfony/property-access", 1910 | "version": "3.4.x-dev", 1911 | "source": { 1912 | "type": "git", 1913 | "url": "https://github.com/symfony/property-access.git", 1914 | "reference": "2740d63e7b3682832a7404bc23b44f651f953f35" 1915 | }, 1916 | "dist": { 1917 | "type": "zip", 1918 | "url": "https://api.github.com/repos/symfony/property-access/zipball/2740d63e7b3682832a7404bc23b44f651f953f35", 1919 | "reference": "2740d63e7b3682832a7404bc23b44f651f953f35", 1920 | "shasum": "" 1921 | }, 1922 | "require": { 1923 | "php": "^5.5.9|>=7.0.8", 1924 | "symfony/inflector": "~3.1|~4.0", 1925 | "symfony/polyfill-php70": "~1.0" 1926 | }, 1927 | "require-dev": { 1928 | "symfony/cache": "~3.1|~4.0" 1929 | }, 1930 | "suggest": { 1931 | "psr/cache-implementation": "To cache access methods." 1932 | }, 1933 | "type": "library", 1934 | "extra": { 1935 | "branch-alias": { 1936 | "dev-master": "3.4-dev" 1937 | } 1938 | }, 1939 | "autoload": { 1940 | "psr-4": { 1941 | "Symfony\\Component\\PropertyAccess\\": "" 1942 | }, 1943 | "exclude-from-classmap": [ 1944 | "/Tests/" 1945 | ] 1946 | }, 1947 | "notification-url": "https://packagist.org/downloads/", 1948 | "license": [ 1949 | "MIT" 1950 | ], 1951 | "authors": [ 1952 | { 1953 | "name": "Fabien Potencier", 1954 | "email": "fabien@symfony.com" 1955 | }, 1956 | { 1957 | "name": "Symfony Community", 1958 | "homepage": "https://symfony.com/contributors" 1959 | } 1960 | ], 1961 | "description": "Symfony PropertyAccess Component", 1962 | "homepage": "https://symfony.com", 1963 | "keywords": [ 1964 | "access", 1965 | "array", 1966 | "extraction", 1967 | "index", 1968 | "injection", 1969 | "object", 1970 | "property", 1971 | "property path", 1972 | "reflection" 1973 | ], 1974 | "time": "2017-09-03T08:01:11+00:00" 1975 | }, 1976 | { 1977 | "name": "symfony/routing", 1978 | "version": "dev-master", 1979 | "source": { 1980 | "type": "git", 1981 | "url": "https://github.com/symfony/routing.git", 1982 | "reference": "aa884694bc1c33fc81f26ad4bb47fd0c04fb2b81" 1983 | }, 1984 | "dist": { 1985 | "type": "zip", 1986 | "url": "https://api.github.com/repos/symfony/routing/zipball/aa884694bc1c33fc81f26ad4bb47fd0c04fb2b81", 1987 | "reference": "aa884694bc1c33fc81f26ad4bb47fd0c04fb2b81", 1988 | "shasum": "" 1989 | }, 1990 | "require": { 1991 | "php": "^7.1.3" 1992 | }, 1993 | "conflict": { 1994 | "symfony/config": "<3.4", 1995 | "symfony/dependency-injection": "<3.4", 1996 | "symfony/yaml": "<3.4" 1997 | }, 1998 | "require-dev": { 1999 | "doctrine/annotations": "~1.0", 2000 | "doctrine/common": "~2.2", 2001 | "psr/log": "~1.0", 2002 | "symfony/config": "~3.4|~4.0", 2003 | "symfony/dependency-injection": "~3.4|~4.0", 2004 | "symfony/expression-language": "~3.4|~4.0", 2005 | "symfony/http-foundation": "~3.4|~4.0", 2006 | "symfony/yaml": "~3.4|~4.0" 2007 | }, 2008 | "suggest": { 2009 | "doctrine/annotations": "For using the annotation loader", 2010 | "symfony/config": "For using the all-in-one router or any loader", 2011 | "symfony/dependency-injection": "For loading routes from a service", 2012 | "symfony/expression-language": "For using expression matching", 2013 | "symfony/http-foundation": "For using a Symfony Request object", 2014 | "symfony/yaml": "For using the YAML loader" 2015 | }, 2016 | "type": "library", 2017 | "extra": { 2018 | "branch-alias": { 2019 | "dev-master": "4.0-dev" 2020 | } 2021 | }, 2022 | "autoload": { 2023 | "psr-4": { 2024 | "Symfony\\Component\\Routing\\": "" 2025 | }, 2026 | "exclude-from-classmap": [ 2027 | "/Tests/" 2028 | ] 2029 | }, 2030 | "notification-url": "https://packagist.org/downloads/", 2031 | "license": [ 2032 | "MIT" 2033 | ], 2034 | "authors": [ 2035 | { 2036 | "name": "Fabien Potencier", 2037 | "email": "fabien@symfony.com" 2038 | }, 2039 | { 2040 | "name": "Symfony Community", 2041 | "homepage": "https://symfony.com/contributors" 2042 | } 2043 | ], 2044 | "description": "Symfony Routing Component", 2045 | "homepage": "https://symfony.com", 2046 | "keywords": [ 2047 | "router", 2048 | "routing", 2049 | "uri", 2050 | "url" 2051 | ], 2052 | "time": "2017-09-03T16:17:01+00:00" 2053 | }, 2054 | { 2055 | "name": "symfony/serializer", 2056 | "version": "3.4.x-dev", 2057 | "source": { 2058 | "type": "git", 2059 | "url": "https://github.com/symfony/serializer.git", 2060 | "reference": "ca9a7c8b8170246b8414bec95fa60d41b372afd9" 2061 | }, 2062 | "dist": { 2063 | "type": "zip", 2064 | "url": "https://api.github.com/repos/symfony/serializer/zipball/ca9a7c8b8170246b8414bec95fa60d41b372afd9", 2065 | "reference": "ca9a7c8b8170246b8414bec95fa60d41b372afd9", 2066 | "shasum": "" 2067 | }, 2068 | "require": { 2069 | "php": "^5.5.9|>=7.0.8" 2070 | }, 2071 | "conflict": { 2072 | "symfony/dependency-injection": "<3.2", 2073 | "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4", 2074 | "symfony/property-info": "<3.1", 2075 | "symfony/yaml": "<3.4" 2076 | }, 2077 | "require-dev": { 2078 | "doctrine/annotations": "~1.0", 2079 | "doctrine/cache": "~1.0", 2080 | "phpdocumentor/reflection-docblock": "^3.0|^4.0", 2081 | "symfony/cache": "~3.1|~4.0", 2082 | "symfony/config": "~2.8|~3.0|~4.0", 2083 | "symfony/dependency-injection": "~3.2|~4.0", 2084 | "symfony/http-foundation": "~2.8|~3.0|~4.0", 2085 | "symfony/property-access": "~2.8|~3.0|~4.0", 2086 | "symfony/property-info": "~3.1|~4.0", 2087 | "symfony/yaml": "~3.4|~4.0" 2088 | }, 2089 | "suggest": { 2090 | "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", 2091 | "doctrine/cache": "For using the default cached annotation reader and metadata cache.", 2092 | "psr/cache-implementation": "For using the metadata cache.", 2093 | "symfony/config": "For using the XML mapping loader.", 2094 | "symfony/http-foundation": "To use the DataUriNormalizer.", 2095 | "symfony/property-access": "For using the ObjectNormalizer.", 2096 | "symfony/property-info": "To deserialize relations.", 2097 | "symfony/yaml": "For using the default YAML mapping loader." 2098 | }, 2099 | "type": "library", 2100 | "extra": { 2101 | "branch-alias": { 2102 | "dev-master": "3.4-dev" 2103 | } 2104 | }, 2105 | "autoload": { 2106 | "psr-4": { 2107 | "Symfony\\Component\\Serializer\\": "" 2108 | }, 2109 | "exclude-from-classmap": [ 2110 | "/Tests/" 2111 | ] 2112 | }, 2113 | "notification-url": "https://packagist.org/downloads/", 2114 | "license": [ 2115 | "MIT" 2116 | ], 2117 | "authors": [ 2118 | { 2119 | "name": "Fabien Potencier", 2120 | "email": "fabien@symfony.com" 2121 | }, 2122 | { 2123 | "name": "Symfony Community", 2124 | "homepage": "https://symfony.com/contributors" 2125 | } 2126 | ], 2127 | "description": "Symfony Serializer Component", 2128 | "homepage": "https://symfony.com", 2129 | "time": "2017-08-17T13:38:59+00:00" 2130 | }, 2131 | { 2132 | "name": "symfony/var-dumper", 2133 | "version": "dev-master", 2134 | "source": { 2135 | "type": "git", 2136 | "url": "https://github.com/symfony/var-dumper.git", 2137 | "reference": "7129cb8f7df318bddbb96564b83195d4cc28c801" 2138 | }, 2139 | "dist": { 2140 | "type": "zip", 2141 | "url": "https://api.github.com/repos/symfony/var-dumper/zipball/7129cb8f7df318bddbb96564b83195d4cc28c801", 2142 | "reference": "7129cb8f7df318bddbb96564b83195d4cc28c801", 2143 | "shasum": "" 2144 | }, 2145 | "require": { 2146 | "php": "^7.1.3", 2147 | "symfony/polyfill-mbstring": "~1.0", 2148 | "symfony/polyfill-php72": "~1.5" 2149 | }, 2150 | "conflict": { 2151 | "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" 2152 | }, 2153 | "require-dev": { 2154 | "ext-iconv": "*", 2155 | "twig/twig": "~1.34|~2.4" 2156 | }, 2157 | "suggest": { 2158 | "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", 2159 | "ext-intl": "To show region name in time zone dump" 2160 | }, 2161 | "type": "library", 2162 | "extra": { 2163 | "branch-alias": { 2164 | "dev-master": "4.0-dev" 2165 | } 2166 | }, 2167 | "autoload": { 2168 | "files": [ 2169 | "Resources/functions/dump.php" 2170 | ], 2171 | "psr-4": { 2172 | "Symfony\\Component\\VarDumper\\": "" 2173 | }, 2174 | "exclude-from-classmap": [ 2175 | "/Tests/" 2176 | ] 2177 | }, 2178 | "notification-url": "https://packagist.org/downloads/", 2179 | "license": [ 2180 | "MIT" 2181 | ], 2182 | "authors": [ 2183 | { 2184 | "name": "Nicolas Grekas", 2185 | "email": "p@tchwork.com" 2186 | }, 2187 | { 2188 | "name": "Symfony Community", 2189 | "homepage": "https://symfony.com/contributors" 2190 | } 2191 | ], 2192 | "description": "Symfony mechanism for exploring and dumping PHP variables", 2193 | "homepage": "https://symfony.com", 2194 | "keywords": [ 2195 | "debug", 2196 | "dump" 2197 | ], 2198 | "time": "2017-09-04T18:35:21+00:00" 2199 | }, 2200 | { 2201 | "name": "symfony/yaml", 2202 | "version": "dev-master", 2203 | "source": { 2204 | "type": "git", 2205 | "url": "https://github.com/symfony/yaml.git", 2206 | "reference": "536404846ea28da89d9e025f31bbce75556d6588" 2207 | }, 2208 | "dist": { 2209 | "type": "zip", 2210 | "url": "https://api.github.com/repos/symfony/yaml/zipball/536404846ea28da89d9e025f31bbce75556d6588", 2211 | "reference": "536404846ea28da89d9e025f31bbce75556d6588", 2212 | "shasum": "" 2213 | }, 2214 | "require": { 2215 | "php": "^7.1.3" 2216 | }, 2217 | "conflict": { 2218 | "symfony/console": "<3.4" 2219 | }, 2220 | "require-dev": { 2221 | "symfony/console": "~3.4|~4.0" 2222 | }, 2223 | "suggest": { 2224 | "symfony/console": "For validating YAML files using the lint command" 2225 | }, 2226 | "type": "library", 2227 | "extra": { 2228 | "branch-alias": { 2229 | "dev-master": "4.0-dev" 2230 | } 2231 | }, 2232 | "autoload": { 2233 | "psr-4": { 2234 | "Symfony\\Component\\Yaml\\": "" 2235 | }, 2236 | "exclude-from-classmap": [ 2237 | "/Tests/" 2238 | ] 2239 | }, 2240 | "notification-url": "https://packagist.org/downloads/", 2241 | "license": [ 2242 | "MIT" 2243 | ], 2244 | "authors": [ 2245 | { 2246 | "name": "Fabien Potencier", 2247 | "email": "fabien@symfony.com" 2248 | }, 2249 | { 2250 | "name": "Symfony Community", 2251 | "homepage": "https://symfony.com/contributors" 2252 | } 2253 | ], 2254 | "description": "Symfony Yaml Component", 2255 | "homepage": "https://symfony.com", 2256 | "time": "2017-09-06T19:16:37+00:00" 2257 | } 2258 | ], 2259 | "packages-dev": [ 2260 | { 2261 | "name": "symfony/dotenv", 2262 | "version": "dev-master", 2263 | "source": { 2264 | "type": "git", 2265 | "url": "https://github.com/symfony/dotenv.git", 2266 | "reference": "7072a5465eb21b03b28a3d9d52b1a87d9a045c6d" 2267 | }, 2268 | "dist": { 2269 | "type": "zip", 2270 | "url": "https://api.github.com/repos/symfony/dotenv/zipball/7072a5465eb21b03b28a3d9d52b1a87d9a045c6d", 2271 | "reference": "7072a5465eb21b03b28a3d9d52b1a87d9a045c6d", 2272 | "shasum": "" 2273 | }, 2274 | "require": { 2275 | "php": "^7.1.3" 2276 | }, 2277 | "require-dev": { 2278 | "symfony/process": "~3.4|~4.0" 2279 | }, 2280 | "type": "library", 2281 | "extra": { 2282 | "branch-alias": { 2283 | "dev-master": "4.0-dev" 2284 | } 2285 | }, 2286 | "autoload": { 2287 | "psr-4": { 2288 | "Symfony\\Component\\Dotenv\\": "" 2289 | }, 2290 | "exclude-from-classmap": [ 2291 | "/Tests/" 2292 | ] 2293 | }, 2294 | "notification-url": "https://packagist.org/downloads/", 2295 | "license": [ 2296 | "MIT" 2297 | ], 2298 | "authors": [ 2299 | { 2300 | "name": "Fabien Potencier", 2301 | "email": "fabien@symfony.com" 2302 | }, 2303 | { 2304 | "name": "Symfony Community", 2305 | "homepage": "https://symfony.com/contributors" 2306 | } 2307 | ], 2308 | "description": "Registers environment variables from a .env file", 2309 | "homepage": "https://symfony.com", 2310 | "keywords": [ 2311 | "dotenv", 2312 | "env", 2313 | "environment" 2314 | ], 2315 | "time": "2017-09-06T19:16:37+00:00" 2316 | } 2317 | ], 2318 | "aliases": [], 2319 | "minimum-stability": "dev", 2320 | "stability-flags": { 2321 | "doctrine/cache": 20, 2322 | "madmis/kuna-api": 20, 2323 | "monolog/monolog": 20, 2324 | "symfony/console": 20, 2325 | "symfony/dependency-injection": 20, 2326 | "symfony/framework-bundle": 20, 2327 | "symfony/var-dumper": 20, 2328 | "symfony/yaml": 20, 2329 | "symfony/dotenv": 20 2330 | }, 2331 | "prefer-stable": false, 2332 | "prefer-lowest": false, 2333 | "platform": { 2334 | "php": "^7.1.3", 2335 | "ext-bcmath": "^7.1" 2336 | }, 2337 | "platform-dev": [] 2338 | } 2339 | --------------------------------------------------------------------------------