[Repo hierhin verschieben]
continuous-integration/drone/push Build is passing Details

This commit is contained in:
xoy 2023-10-04 13:48:05 +02:00
parent de06d2718d
commit debaa449de
646 changed files with 56980 additions and 0 deletions

6
composer.json Normal file
View File

@ -0,0 +1,6 @@
{
"require": {
"twig/twig": "^3.5",
"league/commonmark": "^2.4"
}
}

872
composer.lock generated Normal file
View File

@ -0,0 +1,872 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "7fd366f96757f4d4aff1594a505dd600",
"packages": [
{
"name": "dflydev/dot-access-data",
"version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/dflydev/dflydev-dot-access-data.git",
"reference": "f41715465d65213d644d3141a6a93081be5d3549"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549",
"reference": "f41715465d65213d644d3141a6a93081be5d3549",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.42",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.3",
"scrutinizer/ocular": "1.6.0",
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^4.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Dflydev\\DotAccessData\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dragonfly Development Inc.",
"email": "info@dflydev.com",
"homepage": "http://dflydev.com"
},
{
"name": "Beau Simensen",
"email": "beau@dflydev.com",
"homepage": "http://beausimensen.com"
},
{
"name": "Carlos Frutos",
"email": "carlos@kiwing.it",
"homepage": "https://github.com/cfrutos"
},
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com"
}
],
"description": "Given a deep data structure, access data by dot notation.",
"homepage": "https://github.com/dflydev/dflydev-dot-access-data",
"keywords": [
"access",
"data",
"dot",
"notation"
],
"support": {
"issues": "https://github.com/dflydev/dflydev-dot-access-data/issues",
"source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2"
},
"time": "2022-10-27T11:44:00+00:00"
},
{
"name": "league/commonmark",
"version": "2.4.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d44a24690f16b8c1808bf13b1bd54ae4c63ea048",
"reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"league/config": "^1.1.1",
"php": "^7.4 || ^8.0",
"psr/event-dispatcher": "^1.0",
"symfony/deprecation-contracts": "^2.1 || ^3.0",
"symfony/polyfill-php80": "^1.16"
},
"require-dev": {
"cebe/markdown": "^1.0",
"commonmark/cmark": "0.30.0",
"commonmark/commonmark.js": "0.30.0",
"composer/package-versions-deprecated": "^1.8",
"embed/embed": "^4.4",
"erusev/parsedown": "^1.0",
"ext-json": "*",
"github/gfm": "0.29.0",
"michelf/php-markdown": "^1.4 || ^2.0",
"nyholm/psr7": "^1.5",
"phpstan/phpstan": "^1.8.2",
"phpunit/phpunit": "^9.5.21",
"scrutinizer/ocular": "^1.8.1",
"symfony/finder": "^5.3 | ^6.0",
"symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0",
"unleashedtech/php-coding-standard": "^3.1.1",
"vimeo/psalm": "^4.24.0 || ^5.0.0"
},
"suggest": {
"symfony/yaml": "v2.3+ required if using the Front Matter extension"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.5-dev"
}
},
"autoload": {
"psr-4": {
"League\\CommonMark\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com",
"role": "Lead Developer"
}
],
"description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)",
"homepage": "https://commonmark.thephpleague.com",
"keywords": [
"commonmark",
"flavored",
"gfm",
"github",
"github-flavored",
"markdown",
"md",
"parser"
],
"support": {
"docs": "https://commonmark.thephpleague.com/",
"forum": "https://github.com/thephpleague/commonmark/discussions",
"issues": "https://github.com/thephpleague/commonmark/issues",
"rss": "https://github.com/thephpleague/commonmark/releases.atom",
"source": "https://github.com/thephpleague/commonmark"
},
"funding": [
{
"url": "https://www.colinodell.com/sponsor",
"type": "custom"
},
{
"url": "https://www.paypal.me/colinpodell/10.00",
"type": "custom"
},
{
"url": "https://github.com/colinodell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/league/commonmark",
"type": "tidelift"
}
],
"time": "2023-03-24T15:16:10+00:00"
},
{
"name": "league/config",
"version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/config.git",
"reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
"reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
"shasum": ""
},
"require": {
"dflydev/dot-access-data": "^3.0.1",
"nette/schema": "^1.2",
"php": "^7.4 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^1.8.2",
"phpunit/phpunit": "^9.5.5",
"scrutinizer/ocular": "^1.8.1",
"unleashedtech/php-coding-standard": "^3.1",
"vimeo/psalm": "^4.7.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.2-dev"
}
},
"autoload": {
"psr-4": {
"League\\Config\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com",
"role": "Lead Developer"
}
],
"description": "Define configuration arrays with strict schemas and access values with dot notation",
"homepage": "https://config.thephpleague.com",
"keywords": [
"array",
"config",
"configuration",
"dot",
"dot-access",
"nested",
"schema"
],
"support": {
"docs": "https://config.thephpleague.com/",
"issues": "https://github.com/thephpleague/config/issues",
"rss": "https://github.com/thephpleague/config/releases.atom",
"source": "https://github.com/thephpleague/config"
},
"funding": [
{
"url": "https://www.colinodell.com/sponsor",
"type": "custom"
},
{
"url": "https://www.paypal.me/colinpodell/10.00",
"type": "custom"
},
{
"url": "https://github.com/colinodell",
"type": "github"
}
],
"time": "2022-12-11T20:36:23+00:00"
},
{
"name": "nette/schema",
"version": "v1.2.3",
"source": {
"type": "git",
"url": "https://github.com/nette/schema.git",
"reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/schema/zipball/abbdbb70e0245d5f3bf77874cea1dfb0c930d06f",
"reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f",
"shasum": ""
},
"require": {
"nette/utils": "^2.5.7 || ^3.1.5 || ^4.0",
"php": ">=7.1 <8.3"
},
"require-dev": {
"nette/tester": "^2.3 || ^2.4",
"phpstan/phpstan-nette": "^1.0",
"tracy/tracy": "^2.7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause",
"GPL-2.0-only",
"GPL-3.0-only"
],
"authors": [
{
"name": "David Grudl",
"homepage": "https://davidgrudl.com"
},
{
"name": "Nette Community",
"homepage": "https://nette.org/contributors"
}
],
"description": "📐 Nette Schema: validating data structures against a given Schema.",
"homepage": "https://nette.org",
"keywords": [
"config",
"nette"
],
"support": {
"issues": "https://github.com/nette/schema/issues",
"source": "https://github.com/nette/schema/tree/v1.2.3"
},
"time": "2022-10-13T01:24:26+00:00"
},
{
"name": "nette/utils",
"version": "v4.0.0",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
"reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/utils/zipball/cacdbf5a91a657ede665c541eda28941d4b09c1e",
"reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e",
"shasum": ""
},
"require": {
"php": ">=8.0 <8.3"
},
"conflict": {
"nette/finder": "<3",
"nette/schema": "<1.2.2"
},
"require-dev": {
"jetbrains/phpstorm-attributes": "dev-master",
"nette/tester": "^2.4",
"phpstan/phpstan": "^1.0",
"tracy/tracy": "^2.9"
},
"suggest": {
"ext-gd": "to use Image",
"ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()",
"ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()",
"ext-json": "to use Nette\\Utils\\Json",
"ext-mbstring": "to use Strings::lower() etc...",
"ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()",
"ext-xml": "to use Strings::length() etc. when mbstring is not available"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause",
"GPL-2.0-only",
"GPL-3.0-only"
],
"authors": [
{
"name": "David Grudl",
"homepage": "https://davidgrudl.com"
},
{
"name": "Nette Community",
"homepage": "https://nette.org/contributors"
}
],
"description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.",
"homepage": "https://nette.org",
"keywords": [
"array",
"core",
"datetime",
"images",
"json",
"nette",
"paginator",
"password",
"slugify",
"string",
"unicode",
"utf-8",
"utility",
"validation"
],
"support": {
"issues": "https://github.com/nette/utils/issues",
"source": "https://github.com/nette/utils/tree/v4.0.0"
},
"time": "2023-02-02T10:41:53+00:00"
},
{
"name": "psr/event-dispatcher",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/event-dispatcher.git",
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
"shasum": ""
},
"require": {
"php": ">=7.2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\EventDispatcher\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Standard interfaces for event handling.",
"keywords": [
"events",
"psr",
"psr-14"
],
"support": {
"issues": "https://github.com/php-fig/event-dispatcher/issues",
"source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
},
"time": "2019-01-08T18:20:26+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
"reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
"shasum": ""
},
"require": {
"php": ">=8.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.3-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.1"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-03-01T10:25:55+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-ctype": "*"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-mbstring": "*"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ion Bazan",
"email": "ion.bazan@gmail.com"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "twig/twig",
"version": "v3.5.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "a6e0510cc793912b451fd40ab983a1d28f611c15"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a6e0510cc793912b451fd40ab983a1d28f611c15",
"reference": "a6e0510cc793912b451fd40ab983a1d28f611c15",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3"
},
"require-dev": {
"psr/container": "^1.0",
"symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.5-dev"
}
},
"autoload": {
"psr-4": {
"Twig\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Twig Team",
"role": "Contributors"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com",
"role": "Project Founder"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "https://twig.symfony.com",
"keywords": [
"templating"
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.5.1"
},
"funding": [
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
"type": "tidelift"
}
],
"time": "2023-02-08T07:49:20+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.3.0"
}

4
css/event.css Normal file
View File

@ -0,0 +1,4 @@
img {
display: block;
margin: auto;
}

32
css/events.css Normal file
View File

@ -0,0 +1,32 @@
div.eventblock {
position: relative;
background-color: var(--nav-background-color);
padding: 2px 10px 2px 10px;
margin: 10px 0px 10px 0px;
}
div.eventblock a {
color: white !important;
display: block;
margin: auto;
}
div.eventblock a:hover {
text-decoration: none;
}
div.eventblock h3 {
margin: 0;
}
div.eventblock h3.a {
text-align: left;
width: 50%;
display: inline-block;
}
div.eventblock h3.b {
text-align: right;
width: 50%;
display: inline-block;
}

15
css/home.css Normal file
View File

@ -0,0 +1,15 @@
main img {
max-width: 950px;
width: 100%;
}
main div.rundgang {
height: 140px;
}
@media only screen and (max-width: 885px) {
main img {
height: 140px;
object-fit: cover;
}
}

16
css/kontakt.css Normal file
View File

@ -0,0 +1,16 @@
main {
text-align: center;
}
main a {
display: inline-block;
padding: 20px;
}
main a:hover {
text-decoration: none;
}
main a img {
width: 200px;
}

214
css/main.css Normal file
View File

@ -0,0 +1,214 @@
:root {
--background-color: #193360;
--nav-background-color: #14284c;
--logo-background-color: #0e1e38;
}
* {
box-sizing: border-box;
word-wrap: break-word;
}
html, body {
padding: 0;
margin: 0;
background-color: var(--background-color);
color: white;
font-family: sans-serif;
line-height: 150%;
}
a {
color: #22bb22 !important;
text-decoration: none;
}
a:hover {
text-decoration: underline;
cursor: pointer;
}
a:visited {
color: #bb66ff !important;
}
a.imgLink div {
position: relative;
text-align: center;
color: white;
}
a.imgLink:hover {
text-decoration: none;
}
a.imgLink div {
position: relative;
text-align: center;
color: white !important;
font-size: 0;
transform: scale(1);
transition: transform .5s;
text-shadow: 2px 2px black;
}
a.imgLink:hover div {
font-size: 200%;
transform: scale(.9);
transition: font-size .5s, transform .5s;
}
a.imgLink div h2 {
position: absolute;
top: 35%;
left: 50%;
transform: translate(-50%, -50%);
}
header {
background-color: var(--logo-background-color);
padding: 0 !important;
}
header a#navToggle {
color: white !important;
font-size: 64px;
display: none;
background-color: var(--nav-background-color);
padding: 20px 100px 20px 0;
text-decoration: none !important;
text-align: right;
}
nav {
padding: 10px 0 10px 0;
background-color: var(--nav-background-color);
}
nav ul {
list-style: none;
text-align: center;
}
nav ul li {
display: inline-block;
padding: 0 2vw 0 2vw;
font-size: 125%;
}
nav ul li a {
color: white !important;
text-decoration: none;
}
nav ul li a.active {
text-decoration: underline;
text-decoration-style: double;
}
nav ul li a:visited {
color: white !important;
}
header {
text-align: center;
padding: 10px 0 0 0;
}
header img {
max-width: 200px;
max-height: 200px;
width: 90vw;
margin-bottom: 10px;
}
main {
max-width: 950px;
min-height: 100vh;
height: auto;
width: 90%;
margin: auto;
padding: 10px 0 0 0;
}
footer {
background-color: var(--nav-background-color);
height: 100px;
}
iframe.osm {
width: 500px;
height: 500px;
max-width: 90vw;
max-height: 90vw;
margin: auto;
display: block;
}
div.newBanner {
display: block;
position: fixed;
top: 30px;
left: -40px;
background-color: #DD0000;
text-align: center;
transform: rotateZ(-45deg);
transition: transform .5s;
z-index: 1;
}
div.newBanner:hover {
transform: rotateZ(-45deg) scale(1.4);
transition: transform .5s;
}
div.newBanner a {
color: white !important;
padding: 100px 50px 100px 50px;
}
div.newBanner a:hover {
text-decoration: none;
}
h3.topic {
margin-bottom: 0;
}
p.topic {
margin-top: 0;
}
a.red-text {
color: #DD0000 !important;
}
a.green-text {
color: #00DD00 !important;
}
.text-left {
text-align: left;
}
@media only screen and (max-width: 885px) {
header a#navToggle {
display: block;
}
header nav {
display: none;
}
nav ul li {
display: block;
font-size: 200%;
padding: 30px 100px 30px 0;
text-align: right;
}
a.imgLink div {
font-size: 200%;
}
}

9
events/0.md Normal file
View File

@ -0,0 +1,9 @@
Testeintrag
Ein wunderbarer Testeintrag.
2023-05-10 - 2023-05-16
16:00 - 20:00
Chaostreff Dortmund e.V.
------------------------
# Testeintrag
Dies ist ein wundervoller Test!

15
events/brunch.md Normal file
View File

@ -0,0 +1,15 @@
ChaosBrunch
Einmal in der Woche treffen wir uns regulär zum quatschen, basteln, frickeln, programmieren, hacken, kochen, essen, …
{{ brunchdatum }}
11:00 - 15:00
Chaostreff Dortmund e.V.
------------------------
# ChaosBrunch
Alle zwei Wochen an einem Sonntag lädt der CTDO zum **Mitbring-Brunch** in seinen Räume im Kulturzentrum [„Langer August“](/?page=treff) ein!
Um **ca. 11 Uhr** geht es los, das Ende ist wie immer offen. Die Details dazu gibt es im [ctdo wiki](https://wiki.ctdo.de/events/hackerbrunch)!
Schaut einfach vorab im [MitbringPad](https://md.ctdo.de/brunch) rein und kündigt an was ihr auf den Tisch werft, alles kann, nichts muss!
Es sind sowohl alte als auch neue Menschen gerne gesehen! Bringt was zu futtern, euer aktuelles Projekt, beides oder einfach nur Neugierde mit!

26
events/repaircafe.md Normal file
View File

@ -0,0 +1,26 @@
RepairCafe
“ Wegwerfen? Denkste! „
{{ repaircafedatum }}
19:00 - 23:00
Chaostreff Dortmund e.V.
------------------------
# RepairCafe
![ctdo repaircafe logo](/images/events/ctdo-logo-reperaturcafe.png)
Seit Ende Juni 2014 bietet der Chaostreff Dortmund an jedem letzten Donnerstag im Monat ab 19 Uhr ein Repair Café an. Dazu ist jeder eingeladen, defekte Geräte, sei es der Küchenmixer, Notebook oder der alte Plattenspieler, mitzubringen und selber zu reparieren. Technischen Sachverstand, Rat und auch Tat wird es von uns geben. Wir helfen wo wir können reparieren müsst ihr aber selber das ist der Grundgedanke des Repair Cafés. Als Stärkung haben wir natürlich Getränke und Snacks.
Bereits Anfang Juni 2014 startete unser Repair Cafe, welches wir im Rahmen des Projekts Selber Machen! speziell für Kinder und Jugendliche zwischen 8 und 16 Jahren angeboten haben.
Seit dem Start des normalen Repair Cafes für jedermann/frau konnten wir bereits einigen Geräten neues Leben einhauchen. Manchmal ist es nur eine kalte Lötstelle, ein gebrochenes Kabel oder eine defekte Sicherung, die das gesamte Gerät lahmlegen. Im Wiki gibt es weitere Informationen zum Repair Cafe.
Hier noch mal auf einen Blick:
Repair Café: jeden letzten Donnerstag im Monat ab 19 Uhr im Chaostreff Dortmund
Wir sind auch auf [www.repaircafe.org](https://www.repaircafe.org/) eingetragen.
Du findest uns in der Braunschweiger Str 22, 44145 Dortmund im „Langen August“. Geh durch das große rote Tor und klingel beim „Chaostreff“. Zweites OG. Per E-Mail kannst du uns über die [Mailingliste](/?page=mail) erreichen.
Anmeldung nicht erforderlich!
Achtung: Bei Smartphones, Tablets und zum Großteil bei Apple Produkten können wir leider nicht behilflich sein.

9
events/topictreff.md Normal file
View File

@ -0,0 +1,9 @@
TopicTreff (Plenum)
Der Topictreff ist das zweimal im Monat stattfindende Plenum des CTDO.
{{ topicdatum }}
20:00 - 21:00
Chaostreff Dortmund e.V.
------------------------
# TopicTreff (Plenum)
Der Topictreff ist das zweimal im Monat stattfindende Plenum des CTDO. Aktuelle Themen können im [Wiki](https://wiki.ctdo.de/de/verein/topictreff) eingesehen werden.

13
events/treff.md Normal file
View File

@ -0,0 +1,13 @@
Treff
Einmal in der Woche treffen wir uns regulär zum quatschen, basteln, frickeln, programmieren, hacken, kochen, essen, …
{{ treffdatum }}
19:00 - ende offen
Chaostreff Dortmund e.V.
------------------------
# Treff
Einmal in der Woche treffen wir uns regulär zum quatschen, basteln, frickeln, programmieren, hacken, kochen, essen, …
Los gehts wenn Jemand da ist (meist ab 19 Uhr). Ende offen.
Es darf jeder kommen, egal ob Mitglied oder nicht. Wenn du unsicher bist, ob Jemand da ist, wie lange Jemand bleibt: ruf gerne an, oder frage im Chat nach.

BIN
images/adresse_knopf.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
images/chat_knopf.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
images/header.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

3
images/logo_ctdo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 33 KiB

BIN
images/mail_knopf.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
images/tel_knopf.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

149
index.php Normal file
View File

@ -0,0 +1,149 @@
<?php
require __DIR__ . '/vendor/autoload.php';
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use League\CommonMark\CommonMarkConverter;
require __DIR__ . '/php/util.php';
require __DIR__ . '/php/events.php';
require __DIR__ . '/php/posts.php';
$converter = new CommonMarkConverter([
'html_input' => 'strip',
'allow_unsafe_links' => false,
]);
$templateloader = new FilesystemLoader(__DIR__ . '/templates');
$twig_templates = new Environment($templateloader);
$title = '';
$content = '';
$raumstatus_b = get_web_json('https://status.ctdo.de/api/simple/v2')["state"];
$raumstatus = '<b>unbekannt</b>';
$pages = array('index', 'about', 'treff', 'blog', 'events', 'kontakt', 'support', 'verein');
$page_names = array('index', 'über uns', 'zeiten & location', 'blog', 'events', 'kontakt', 'support', 'verein');
$active_page = '';
if(gettype($raumstatus_b) == "boolean") {
if($raumstatus_b)
$raumstatus = html_link('https://status.ctdo.de/', 'green-text', '<b>offen</b>', TRUE);
else
$raumstatus = html_link('https://status.ctdo.de/', 'red-text', '<b>geschlossen</b>', TRUE);
}
$topic = get_next_topic();
$treff = get_next_treff();
$repaircafe = get_next_repaircafe();
$brunch = get_next_brunch();
$css = ['main'];
if(isset($_GET['page'])) {
$page = $_GET['page'];
$active_page = str_mass_replace(array('adresse', 'irc', 'mail'), array('kontakt', 'kontakt', 'kontakt'), $page);
$title = $page_names[array_search($active_page, $pages)];
switch ($page) {
case 'index':
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/index.md'));
$content = $twig_templates->render('index.twig', ['content' => $content, 'topic' => $topic, 'treff' => $treff, 'repaircafe' => $repaircafe, 'brunch' => $brunch, 'events' => generate_event_list() ]);
$filetoedit = "pages/index.md";
$css[] = 'home';
$css[] = 'events';
break;
case 'about':
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/about.md'));
$filetoedit = "pages/about.md";
$css[] = 'about';
break;
case 'treff':
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/treff.md'));
$filetoedit = "pages/treff.md";
break;
case 'blog':
if(!isset($_GET['id'])) {
$content = $twig_templates->render('blog.twig', [ 'posts' => generate_post_list() ]);
$filetoedit = "templates/blog.twig";
$css[] = 'events';
} else {
$content = $converter->convert(get_post_content($_GET['id']));
$filetoedit = "posts/".$_GET['id'].".md";
$css[] = 'event';
}
break;
case 'events':
if(!isset($_GET['id'])) {
$content = $twig_templates->render('events.twig', [ 'topic' => $topic, 'treff' => $treff, 'repaircafe' => $repaircafe, 'brunch' => $brunch, 'events' => generate_event_list() ]);
$filetoedit = "templates/events.twig";
$css[] = 'events';
} else {
$content = str_mass_replace(array('{{ topicdatum }}', 'Chaostreff Dortmund e.V.', '{{ treffdatum }}', '{{ repaircafedatum }}', '{{ brunchdatum }}'), array(get_next_topic()->date, html_link('/?page=treff', '', 'Chaostreff Dortmund e.V.', FALSE), get_next_treff()->date, get_next_repaircafe()->date, get_next_brunch()->date), $converter->convert(get_event_content($_GET['id'])));
$filetoedit = "events/".$_GET['id'].".md";
$css[] = 'event';
}
break;
case 'kontakt':
$content = $twig_templates->render('kontakt.twig');
$filetoedit = "templates/kontakt.twig";
$css[] = 'kontakt';
break;
case 'adresse':
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/kontakt/adresse.md')).'<iframe scrolling="no" marginheight="0" marginwidth="0" src="https://www.openstreetmap.org/export/embed.html?bbox=7.463200986385346%2C51.52693021432671%2C7.4667415022850046%2C51.52841869497588&amp;layer=mapnik&amp;marker=51.52767446073405%2C7.464971244335175" frameborder="0" class="osm"></iframe>';
$filetoedit = "pages/kontakt/adresse.md";
break;
case 'irc':
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/kontakt/irc.md'));
$filetoedit = "pages/kontakt/irc.md";
break;
case 'mail':
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/kontakt/mail.md'));
$filetoedit = "pages/kontakt/mail.md";
break;
case 'tel':
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/kontakt/tel.md'));
$filetoedit = "pages/kontakt/tel.md";
break;
case 'support':
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/support.md'));
$filetoedit = "pages/kontakt/support.md";
break;
case 'verein':
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/verein.md'));
$filetoedit = "pages/verein.md";
break;
case 'impressum':
$title = 'impressum';
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/impressum.md'));
$filetoedit = "pages/impressum.md";
break;
case 'datenschutz':
$title = 'datenschutz';
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/datenschutz.md'));
$filetoedit = "pages/datenschutz.md";
break;
default:
$content = $twig_templates->render('404.twig', ['page' => $_GET['page']]);
$filetoedit = "templates/404.twig";
break;
}
} else {
$active_page = 'index';
$title = $active_page;
$content = $converter->convert(file_get_contents(__DIR__ . '/pages/index.md'));
$content = $twig_templates->render('index.twig', ['content' => $content, 'topic' => $topic, 'treff' => $treff, 'repaircafe' => $repaircafe, 'brunch' => $brunch, 'events' => generate_event_list() ]);
$css[] = 'home';
$css[] = 'events';
}
$nav = generate_nav($active_page, $pages, $page_names);
echo $twig_templates->render('default.twig', ['title' => $title, 'css' => $css, 'nav' => $nav, 'raumstatus' => $raumstatus, 'main' => $content, 'file_to_edit' => $filetoedit]);
?>

18
js/nav.js Normal file
View File

@ -0,0 +1,18 @@
var nav = document.getElementsByTagName("nav")[0];
function ToggleNav() {
showNav = nav.style.display != "" && nav.style.display != "none";
if (showNav) {
nav.style.display = "none";
} else {
nav.style.display = "block";
}
}
window.addEventListener("resize", function(){
if (window.innerWidth > 885) {
nav.style.display = "block";
} else {
nav.style.display = "none";
}
});

48
pages/about.md Normal file
View File

@ -0,0 +1,48 @@
# Wer wir sind
Der Chaostreff Dortmund e.V. ist ein Erfa-Kreis des CCC* und eine bunt gemischte Gruppe aus computer-, technikbegeisterten und kreativen Menschen. Wir sind nicht finanziell orientiert und betreiben den Chaostreff aus Spaß an der Sache und um interessierten Menschen eine Plattform zu bieten, über die man sich austauschen kann. Unser Ziel ist es den Chaostreff fortwährend aus Spenden der einzelnen Teilnehmenden bzw. Mitglieder zu finanzieren. Wenn du dir angucken möchtest, wie das so bei uns in den Räumen aussieht, dann komm doch einfach vorbei.
Wir schließen niemanden aufgrund körperlicher Disposition, Religion, Alter, Weltanschauung, sexueller Ausrichtung oder sonstigen nichtigen Gründen aus! Alle, die interessiert sind, sind auch bei uns willkommen.
*Wir sind ein Teil des Chaos Computer Club (CCC), ein s. g. Erfa Kreis (Erfahrungsaustausch Kreis), da wir seit 2017-04-16¹ den Erfa Status vom Regiotreff zuerkannt bekommen haben.
# Unsere Ziele
- Schaffung einer Plattform für technikbegeisterte Menschen
- Bereitstellung einer technischen Infrastruktur
- Gemütliche Räumlichkeiten mit Getränken etc.
- Die Möglichkeit, gemeinsam kreativ mit Technik umzugehen
- Nützliches Mitglied des Nordstadtquartiers zu sein
- Sich und andere weiterzubilden
- Weltherrschaft natürlich!²
# Unsere Zielgruppe
Alle, die sich für Technik, Kunst, Kreativität, OpenSource, Netzpolitik, den Geist in der Maschine oder ähnliches begeistern können; wie bereits oben erwähnt schließen wir niemanden aus irgendwelchen dämlichen/rassistischen/vorurteilsbehafteten Gründen aus.
Wir freuen uns schon auf deinen ersten Besuch bei uns.
# Wir bieten dir
- Viel Platz für eigene Projekte
- Chillout Platz mit Sofas und gemütlicher Atmosphäre
- Eine Küche zum gemeinsamen Kochen
- Einen Raum für Siebdruck und Platinenherstellung
- Maschinen wie Lasercutter, Stickmaschine, 3D Drucker
- Werkzeuge, sowie Lötarbeitsplätze und Messgeräte
- PC-Arbeitsplätze
- Email/Shell Konten und Webspace oder VServer
- Kisten/Regale damit du dein Zeug verstauen kannst
- Freundliche Leute mit denen man sich austauschen kann
- u.v.m
# Du gehörst nicht zu uns, wenn…
- …du einen 24/7 kostenlosen PC-Hilfe Notdienst suchst.
- …deine Festplatte kaputt ist, und du vergessen hast, ein Backup zu machen. (Ausnahmen bestätigen die Regel)
- …du der Meinung bist, wir wären dein kostenloses Internetcafé
- …du der irrigen Annahme verfallen bist, wir würden für dich irgendeinen FTP-/WebServer/eMail-Account-deiner-ExFreundin hacken, geschweige denn dir dabei helfen
¹ [https://en.wikipedia.org/wiki/ISO_8601](https://en.wikipedia.org/wiki/ISO_8601)
² Dies ist eine witzige Bemerkung ein s.g. “Running Gag” und ist als sarkastische Bemerkung zu verstehen!

252
pages/datenschutz.md Normal file
View File

@ -0,0 +1,252 @@
# Datenschutzerklärung
*(English version below)*
## 1. Datenschutz auf einen Blick
### Allgemeine Hinweise
Die folgenden Hinweise geben einen einfachen Überblick darüber, was mit Ihren personenbezogenen Daten passiert, wenn Sie unsere Website besuchen. Personenbezogene Daten sind alle Daten, mit denen Sie persönlich identifiziert werden können. Ausführliche Informationen zum Thema Datenschutz entnehmen Sie unserer unter diesem Text aufgeführten Datenschutzerklärung.
### Datenerfassung auf unserer Website
#### Wer ist verantwortlich für die Datenerfassung auf dieser Website?
Die Datenverarbeitung auf dieser Website erfolgt durch den Websitebetreiber. Dessen Kontaktdaten können Sie dem Impressum dieser Website entnehmen.
#### Wie erfassen wir Ihre Daten?
Ihre Daten werden zum einen dadurch erhoben, dass Sie uns diese mitteilen. Hierbei kann es sich z.B. um Daten handeln, die Sie in ein Kontaktformular eingeben.
Andere Daten werden automatisch beim Besuch der Website durch unsere IT-Systeme erfasst. Das sind vor allem technische Daten (z.B. Internetbrowser, Betriebssystem oder Uhrzeit des Seitenaufrufs). Die Erfassung dieser Daten erfolgt automatisch, sobald Sie unsere Website betreten.
#### Wofür nutzen wir Ihre Daten?
Ein Teil der Daten wird erhoben, um eine fehlerfreie Bereitstellung der Website zu gewährleisten. Andere Daten können zur Analyse Ihres Nutzerverhaltens verwendet werden.
#### Welche Rechte haben Sie bezüglich Ihrer Daten?
Sie haben jederzeit das Recht unentgeltlich Auskunft über Herkunft, Empfänger und Zweck Ihrer gespeicherten personenbezogenen Daten zu erhalten. Sie haben außerdem ein Recht, die Berichtigung, Sperrung oder Löschung dieser Daten zu verlangen. Hierzu sowie zu weiteren Fragen zum Thema Datenschutz können Sie sich jederzeit unter der im Impressum angegebenen Adresse an uns wenden. Des Weiteren steht Ihnen ein Beschwerderecht bei der zuständigen Aufsichtsbehörde zu.
## 2. Allgemeine Hinweise und Pflichtinformationen
### Datenschutz
Die Betreiber dieser Seiten nehmen den Schutz Ihrer persönlichen Daten sehr ernst. Wir behandeln Ihre personenbezogenen Daten vertraulich und entsprechend der gesetzlichen Datenschutzvorschriften sowie dieser Datenschutzerklärung.
Wenn Sie diese Website benutzen, werden verschiedene personenbezogene Daten erhoben. Personenbezogene Daten sind Daten, mit denen Sie persönlich identifiziert werden können. Die vorliegende Datenschutzerklärung erläutert, welche Daten wir erheben und wofür wir sie nutzen. Sie erläutert auch, wie und zu welchem Zweck das geschieht.
Wir weisen darauf hin, dass die Datenübertragung im Internet (z.B. bei der Kommunikation per E-Mail) Sicherheitslücken aufweisen kann. Ein lückenloser Schutz der Daten vor dem Zugriff durch Dritte ist nicht möglich.
### Hinweis zur verantwortlichen Stelle
Die verantwortliche Stelle für die Datenverarbeitung auf dieser Website ist:
```
Chaostreff Dortmund e.V.
Braunschweiger Str. 22
44145 Dortmund
Deutschland
```
#### Vertretungsberechtigter Vorstand
- Tim Windelschmidt (1. Vorsitzender)
- Stefan Hausschild (2. Vorsitzender)
Telefon: [+49 (0)231 8 404 777](tel:+492318404777)
E-Mail: [vorstand@chaostreff-dortmund.de](mailto:vorstand@chaostreff-dortmund.de)
Verantwortliche Stelle ist die natürliche oder juristische Person, die allein oder gemeinsam mit anderen über die Zwecke und Mittel der Verarbeitung von personenbezogenen Daten (z.B. Namen, E-Mail-Adressen o. Ä.) entscheidet.
### Widerruf Ihrer Einwilligung zur Datenverarbeitung
Viele Datenverarbeitungsvorgänge sind nur mit Ihrer ausdrücklichen Einwilligung möglich. Sie können eine bereits erteilte Einwilligung jederzeit widerrufen. Dazu reicht eine formlose Mitteilung per E-Mail an uns. Die Rechtmäßigkeit der bis zum Widerruf erfolgten Datenverarbeitung bleibt vom Widerruf unberührt.
### Beschwerderecht bei der zuständigen Aufsichtsbehörde
Im Falle datenschutzrechtlicher Verstöße steht dem Betroffenen ein Beschwerderecht bei der zuständigen Aufsichtsbehörde zu. Zuständige Aufsichtsbehörde in datenschutzrechtlichen Fragen ist der Landesdatenschutzbeauftragte des Bundeslandes, in dem unser Unternehmen seinen Sitz hat. Eine Liste der Datenschutzbeauftragten sowie deren Kontaktdaten können folgendem Link entnommen werden: [https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html](https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html).
### Recht auf Datenübertragbarkeit
Sie haben das Recht, Daten, die wir auf Grundlage Ihrer Einwilligung oder in Erfüllung eines Vertrags automatisiert verarbeiten, an sich oder an einen Dritten in einem gängigen, maschinenlesbaren Format aushändigen zu lassen. Sofern Sie die direkte Übertragung der Daten an einen anderen Verantwortlichen verlangen, erfolgt dies nur, soweit es technisch machbar ist.
### SSL- bzw. TLS-Verschlüsselung
Diese Seite nutzt aus Sicherheitsgründen und zum Schutz der Übertragung vertraulicher Inhalte, wie zum Beispiel Bestellungen oder Anfragen, die Sie an uns als Seitenbetreiber senden, eine SSL-bzw. TLS-Verschlüsselung. Eine verschlüsselte Verbindung erkennen Sie daran, dass die Adresszeile des Browsers von “http://” auf “https://” wechselt und an dem Schloss-Symbol in Ihrer Browserzeile.
Wenn die SSL- bzw. TLS-Verschlüsselung aktiviert ist, können die Daten, die Sie an uns übermitteln, nicht von Dritten mitgelesen werden.
### Auskunft, Sperrung, Löschung
Sie haben im Rahmen der geltenden gesetzlichen Bestimmungen jederzeit das Recht auf unentgeltliche Auskunft über Ihre gespeicherten personenbezogenen Daten, deren Herkunft und Empfänger und den Zweck der Datenverarbeitung und ggf. ein Recht auf Berichtigung, Sperrung oder Löschung dieser Daten. Hierzu sowie zu weiteren Fragen zum Thema personenbezogene Daten können Sie sich jederzeit unter der im Impressum angegebenen Adresse an uns wenden.
## 3. Datenerfassung auf unserer Website
### Server-Log-Dateien
Der Provider der Seiten erhebt und speichert automatisch Informationen in so genannten Server-Log-Dateien, die Ihr Browser automatisch an uns übermittelt. Dies sind:
- Browsertyp und Browserversion
- verwendetes Betriebssystem
- Referrer URL
- Hostname des zugreifenden Rechners
- Uhrzeit der Serveranfrage
- IP-Adresse
Eine Zusammenführung dieser Daten mit anderen Datenquellen wird nicht vorgenommen.
Grundlage für die Datenverarbeitung ist Art. 6 Abs. 1 lit. f DSGVO, der die Verarbeitung von Daten zur Erfüllung eines Vertrags oder vorvertraglicher Maßnahmen gestattet.
## 4. Plugins und Tools
### YouTube
Unsere Website nutzt Plugins der von Google betriebenen Seite YouTube. Betreiber der Seiten ist die YouTube, LLC, 901 Cherry Ave., San Bruno, CA 94066, USA.
Wenn Sie eine unserer mit einem YouTube-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von YouTube hergestellt. Dabei wird dem YouTube-Server mitgeteilt, welche unserer Seiten Sie besucht haben.
Wenn Sie in Ihrem YouTube-Account eingeloggt sind, ermöglichen Sie YouTube, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem YouTube-Account ausloggen.
Die Nutzung von YouTube erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne von Art. 6 Abs. 1 lit. f DSGVO dar.
Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von YouTube unter: [https://www.google.de/intl/de/policies/privacy](https://www.google.de/intl/de/policies/privacy).
### Vimeo
Unsere Website nutzt Plugins des Videoportals Vimeo. Anbieter ist die Vimeo Inc., 555 West 18th Street, New York, New York 10011, USA.
Wenn Sie eine unserer mit einem Vimeo-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von Vimeo hergestellt. Dabei wird dem Vimeo-Server mitgeteilt, welche unserer Seiten Sie besucht haben. Zudem erlangt Vimeo Ihre IP-Adresse. Dies gilt auch dann, wenn Sie nicht bei Vimeo eingeloggt sind oder keinen Account bei Vimeo besitzen. Die von Vimeo erfassten Informationen werden an den Vimeo-Server in den USA übermittelt.
Wenn Sie in Ihrem Vimeo-Account eingeloggt sind, ermöglichen Sie Vimeo, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem Vimeo-Account ausloggen.
Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Vimeo unter: [https://vimeo.com/privacy](https://vimeo.com/privacy).
# Privacy Policy
## 1. An overview of data protection
### General
The following gives a simple overview of what happens to your personal information when you visit our website. Personal information is any data with which you could be personally identified. Detailed information on the subject of data protection can be found in our privacy policy found below.
### Data collection on our website
#### Who is responsible for the data collection on this website?
The data collected on this website are processed by the website operator. The operators contact details can be found in the websites required legal notice.
#### How do we collect your data?
Some data are collected when you provide it to us. This could, for example, be data you enter on a contact form.
Other data are collected automatically by our IT systems when you visit the website. These data are primarily technical data such as the browser and operating system you are using or when you accessed the page. These data are collected automatically as soon as you enter our website.
#### What do we use your data for?
Part of the data is collected to ensure the proper functioning of the website. Other data can be used to analyze how visitors use the site.
#### What rights do you have regarding your data?
You always have the right to request information about your stored data, its origin, its recipients, and the purpose of its collection at no charge. You also have the right to request that it be corrected, blocked, or deleted. You can contact us at any time using the address given in the legal notice if you have further questions about the issue of privacy and data protection. You may also, of course, file a complaint with the competent regulatory authorities.
## 2. General information and mandatory information
### Data protection
The operators of this website take the protection of your personal data very seriously. We treat your personal data as confidential and in accordance with the statutory data protection regulations and this privacy policy.
If you use this website, various pieces of personal data will be collected. Personal information is any data with which you could be personally identified. This privacy policy explains what information we collect and what we use it for. It also explains how and for what purpose this happens.
Please note that data transmitted via the internet (e.g. via email communication) may be subject to security breaches. Complete protection of your data from third-party access is not possible.
### Notice concerning the party responsible for this website
The party responsible for processing data on this website is:
```
Chaostreff Dortmund e.V.
Braunschweiger Str. 22
44145 Dortmund
Germany
```
#### Authorized representatives
- Tim Windelschmidt (1. Vorsitzender)
- Stefan Hausschild (2. Vorsitzender)
Telefon: [+49 (0)231 8 404 777](tel:+492318404777)
E-Mail: [vorstand@chaostreff-dortmund.de](mailto:vorstand@chaostreff-dortmund.de)
The responsible party is the natural or legal person who alone or jointly with others decides on the purposes and means of processing personal data (names, email addresses, etc.).
### Revocation of your consent to the processing of your data
Many data processing operations are only possible with your express consent. You may revoke your consent at any time with future effect. An informal email making this request is sufficient. The data processed before we receive your request may still be legally processed.
### Right to file complaints with regulatory authorities
<p>If there has been a breach of data protection legislation, the person affected may file a complaint with the competent regulatory authorities. The competent regulatory authority for matters related to data protection legislation is the data protection officer of the German state in which our company is headquartered. A list of data protection officers and their contact details can be found at the following link: [https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html](https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html).
### Right to data portability
You have the right to have data which we process based on your consent or in fulfillment of a contract automatically delivered to yourself or to a third party in a standard, machine-readable format. If you require the direct transfer of data to another responsible party, this will only be done to the extent technically feasible.
### SSL or TLS encryption
This site uses SSL or TLS encryption for security reasons and for the protection of the transmission of confidential content, such as the inquiries you send to us as the site operator. You can recognize an encrypted connection in your browsers address line when it changes from „http://“ to „https://“ and the lock icon is displayed in your browsers address bar.
If SSL or TLS encryption is activated, the data you transfer to us cannot be read by third parties.
### Information, blocking, deletion
As permitted by law, you have the right to be provided at any time with information free of charge about any of your personal data that is stored as well as its origin, the recipient and the purpose for which it has been processed. You also have the right to have this data corrected, blocked or deleted. You can contact us at any time using the address given in our legal notice if you have further questions on the topic of personal data.
## 3. Data collection on our website
### Server log files
The website provider automatically collects and stores information that your browser automatically transmits to us in „server log files“. These are:
- Browser type and browser version
- Operating system used
- Referrer URL
- Host name of the accessing computer
- Time of the server request
- IP address
These data will not be combined with data from other sources.
The basis for data processing is Art. 6 (1) (f) DSGVO, which allows the processing of data to fulfill a contract or for measures preliminary to a contract.
## 4. Plugins and tools
### YouTube
Our website uses plugins from YouTube, which is operated by Google. The operator of the pages is YouTube LLC, 901 Cherry Ave., San Bruno, CA 94066, USA.
If you visit one of our pages featuring a YouTube plugin, a connection to the YouTube servers is established. Here the YouTube server is informed about which of our pages you have visited.
If youre logged in to your YouTube account, YouTube allows you to associate your browsing behavior directly with your personal profile. You can prevent this by logging out of your YouTube account.
YouTube is used to help make our website appealing. This constitutes a justified interest pursuant to Art. 6 (1) (f) DSGVO.
Further information about handling user data, can be found in the data protection declaration of YouTube under [https://www.google.de/intl/de/policies/privacy](https://www.google.de/intl/de/policies/privacy).
### Vimeo
Our website uses features provided by the Vimeo video portal. This service is provided by Vimeo Inc., 555 West 18th Street, New York, New York 10011, USA.
If you visit one of our pages featuring a Vimeo plugin, a connection to the Vimeo servers is established. Here the Vimeo server is informed about which of our pages you have visited. In addition, Vimeo will receive your IP address. This also applies if you are not logged in to Vimeo when you visit our website or do not have a Vimeo account. The information is ransmitted to a Vimeo server in the US, where it is stored.
If you are logged in to your Vimeo account, Vimeo allows you to associate your browsing behavior directly with your personal profile. You can prevent this by logging out of your Vimeo account.
For more information on how to handle user data, please refer to the Vimeo Privacy Policy at [https://vimeo.com/privacy](https://vimeo.com/privacy).

45
pages/impressum.md Normal file
View File

@ -0,0 +1,45 @@
# Impressum
## Postanschrift
```
Chaostreff Dortmund e.V.
Braunschweiger Str. 22
44145 Dortmund
Deutschland
```
### Vertretungsberechtigter Vorstand
- Tim Windelschmidt (1. Vorsitzender)
- Stefan Hausschild (2. Vorsitzender)
- Jan Münch (Kassenwart)
## E-Mail
- Presseanfragen bitte per E-Mail an unsere Pressestelle [presse@chaostreff-dortmund.de](mailto:presse@chaostreff-dortmund.de)
- Netz-Missbrauch Meldungen an die abuse-addresse [abuse@chaostreff-dortmund.de](mailto:abuse@chaostreff-dortmund.de)
- Anfragen bezüglich inhaltlicher Gestaltung bitte per E-Mail an den Webmaster [webmaster@chaostreff-dortmund.de](mailto:webmaster@chaostreff-dortmund.de)
- Technischer Kontakt: [postmaster@chaostreff-dortmund.de](mailto:postmaster@chaostreff-dortmund.de)
## Telefon
- Chaos-Raum (Di+Do ab ca 19Uhr): [+49 (0)231 8 404 777](tel:+492318404777)
- Fax: +49 (0)231 8 404 779
## Kontodaten
```
Empfänger: Chaostreff Dortmund e.V.
IBAN: DE19 4306 0967 4009 3686 00
BIC: GENODEM1GLS
```
## Logo
Unser Logo für die Verarbeitung in redaktionellen Inhalten und sonstigen Presse-Erzeugnissen findet Ihr [hier](https://www.chaostreff-dortmund.de/presse/logo)
## Flyer
Unseren Aktuellen Fyler als PDF gibt es [hier](https://www.chaostreff-dortmund.de/presse/flyer/)

12
pages/index.md Normal file
View File

@ -0,0 +1,12 @@
[![Raum 2 mit gemütlichen Sofas](/images/header.jpg)](https://www.chaostreff-dortmund.de/rundgang/)
# Hi
Wir sind eine bunt gemischte Gruppe aus computer-, technikbegeisterten und kreativen Menschen. Wir betreiben den Chaostreff aus Spaß an der Sache und um interessierten Menschen eine Plattform zu bieten, über die man sich austauschen kann.
Wenn du Lust hast dir das mal anzuschauen, dann komm gerne vorbei. [zeiten & location](/?page=treff)
Egal wer du bist, egal was du machst bei uns sind alle Menschen willkommen. Leider sind unsere Räume aktuell nicht barrierefrei.
Falls du Fragen hast schreibe uns an. [kontakt](/?page=kontakt)
Wenn du mehr über uns wissen möchtest, schau hier: [über uns](/?page=about)

9
pages/kontakt/adresse.md Normal file
View File

@ -0,0 +1,9 @@
[Zurück](?page=kontakt)
# Adresse
```
Chaostreff Dortmund e.V.
Braunschweiger Str. 22
44145 Dortmund
Deutschland
```

34
pages/kontakt/irc.md Normal file
View File

@ -0,0 +1,34 @@
[Zurück](?page=kontakt)
# IRC
Wir sind im Hackint IRC-Netzwerk erreichbar, der Server ist **irc.hackint.org** (SSL Port **6697**), Channel **#ccc.do**.
Um Missverständnisse und böses Blut zu vermeiden, hier mal reinschauen:
[RFC-1855](https://tools.ietf.org/html/rfc1855), [RFC-2811](https://tools.ietf.org/html/rfc2811)
## Warum Hackint
Das Hackint-Netzwerk wurde unter anderem vom Chaostreff Dortmund ins Leben gerufen, um eine einfache und trotzdem sichere Kommunikation zu ermöglichen. Um das zu gewährleisten sind alle Server-Verbindungen verschlüsselt und alle Server ermöglichen den Benutzern eine verschlüsselte Verbindung via SSL aufzubauen. Eines der Ziele des Hackints ist es, eine Heimat für Hacker, Haecksen und ähnliche Leute auf der ganzen Welt zu schaffen und einfache Verbindungen zwischen einzelnen Gruppen zu ermöglichen. Damit das klappt, müssen sich möglichst viele chaosnahe Gruppen in diesem Netz anfinden.
## Anleitung für des IRCens Unkundige
### Einen IRC-Client suchen
Unix/Linux-nutzende können [HexChat](https://hexchat.github.io/) benutzen, oder, für das CLI-Feeling weechat oder irssi.
Windows-nutzenden ist ebenfalls [HexChat](https://hexchat.github.io/) zu empfehlen.
todo: Macs
### Konfiguration von HexChat
Als erstes muss du dir einen Nick-(Spitz-)namen ausdenken. Jede Person hat einen einzigartigen Nick, daher nicht wundern wenn gängige Namen schon vergeben sind. Ein Nick darf maximal 15 Buchstaben/Zahlen lang sein. Sonderzeichen funktionieren zwar, sehen aber komisch aus.
Wenn du einen Nick gefunden hast, klick bei den Netzwerken aufs Plus. Dort vergibst du den Namen "hackint" und klickst direkt weiter auf bearbeiten. Statt dem voreingetragenen Server schreib dort irc.hackint.org/6697 hin. Dann wähle den Haken um SSL für alle Server des Netzwerks zu verwenden an. Nur noch die Netzwerkkonfiguration schließen und auf verbinden klicken.
Nach dem Verbinden sollte HexChat fragen welchem Channel du joinen möchtest. Gib dort #ccc.do ein und drücke ok.
\o/ du kannst uns jetzt Nachrichten schreiben.

45
pages/kontakt/mail.md Normal file
View File

@ -0,0 +1,45 @@
[Zurück](?page=kontakt)
# eMail
Wenn du eine einfache Anfrage hast, schreib einfach an unsere Mailingliste (aber schreib bitte dabei, dass du nicht auf der Liste eingetragen bist. Sonst erreichen dich die Antworten möglicherweise nicht). Wenn du dich zum Chaostreff gesellen möchtest, trägst du dich am besten auf der Liste ein.
Unsere Mailinglist ist unter [discuss@lists.chaostreff-dortmund.de](mailto:discuss@lists.chaostreff-dortmund.de), diese ist auch unsere öffentliche Mailingliste.
Presse: [presse@chaostreff-dortmund.de](mailto:presse@chaostreff-dortmund.de)
Spenden: [spenden@chaostreff-dortmund.de](mailto:spenden@chaostreff-dortmund.de)
## Subscriben/Unsubscriben auf die Mailingliste
Die Mailingliste wird von Mailman gemanaged und ist offen für alle. Subscriben kann man sich auf der Mailingliste, indem man auf die [Mailman](https://lists.chaostreff-dortmund.de/cgi-bin/mailman/listinfo/discuss) Seite geht und sich dort einträgt.
## Was ist so auf der Mailingliste
Alle Chaostreff-Aktivitäten werden (sollten zumindest) über die Mailingliste geplant oder zumindest angekündigt. Wenn man nur wissen möchte, was der Chaostreff gerade so macht, kann man natürlich auch regelmässig auf unsere Webseite gucken. Wenn man wirklich wissen möchte was gerade geht, sollte man sich auf die Mailingliste eintragen. Hier können und werden aktuelle Weltherrschaftspläne geschmiedet¹, Kontakte geschlossen, und auch sonstige, den Chaostreff betreffende, Themen besprochen.
¹liebes Finanzamt, das ist nur Spaß :)
Außerdem findet man alles was für den Chaostreff von Interesse sein könnte und mit dem ein entfernter Bezug zum Chaostreff hergestellt werden kann. Also von Diskussionen zu aktueller Hardware und dem kreativen Umgang damit, über die neuesten Fort- und Rückschritte in aktuellen Gesetzgebungsverfahren und anderen Zeitgeschehen.
Grundsätzlich gilt: Die Mailingliste ist nicht readonly und lebt durch eure Postings. Also postet!
## FAQ
### Wer kann die Subscriptions lesen?
Jeder der auf der Liste subscribed ist kann sich die Subscriber-Liste ansehen.
### Warum kommt meine Mail nicht auf der Mailingliste an?
Damit die Mailingliste nicht als Spam-Multiplexer fungiert, ist sie so konfiguriert, dass alle Mails, die nicht eine auf der Liste eingetragene Mailaddresse im From: Header stehen haben, erstmal zur Moderator Mailingliste weitergeleitet werden. Da auch Moderatoren noch ein anderes Leben haben, kann das dann etwas dauern.
### Wer sind diese Moderatoren?
Zur Zeit: tarja, fisch und claas
### Ich habe technische Probleme
Bei technischen Problemen (subscription passt nicht) kann dem Listen-Owner geschrieben werden. Diese/r wird versuchen, dich innerhalb ihrer/seiner Möglichkeiten, nach bestem Wissen und Gewissen, zu unterstützen.

5
pages/kontakt/tel.md Normal file
View File

@ -0,0 +1,5 @@
[Zurück](?page=kontakt)
# Telefon
Wenn du eher auf Voice-Communication stehst (oder einfach wissen willst, ob jemand im Raum ist), kannst du uns auch anrufen: Es klingelt im Raum, wenn man [+49 (0)231 8 404 777](tel:+492318404777) wählt.

23
pages/support.md Normal file
View File

@ -0,0 +1,23 @@
# Spenden
Der Chaostreff Dortmund finanziert sich vollkommen aus sich selbst: Das bedeutet aus dem Portemonnaie seiner Mitglieder und oder derer, die den Treff für sinnvoll halten.
## Wieso und wofür?
Wir haben gewisse Kosten zu decken, dazu gehören die Miete, Kosten für Heizung, Strom und Internet. Letztere Punkte werden durch das positive Klima im Langen August für uns sehr angenehm gehalten. Damit ist jedoch gerade einmal die grundsätzliche Infrastruktur geschaffen.
Für Projekte fehlt es dem Treff schon wieder an Geld. Allein die Finanzierung der gemeinsamen Räume basiert Gerüchten zufolge eher auf einer raffinierten Mate-Wiederverkaufsstrategie in Kombination mit einer Ausnutzung der suchterregenden Auswirkungen dieses Getränks.
Als groben Richtwert kann man sagen, dass der Spendendurchschnitt irgendwo zwischen 23 und 42 Euro monatlich liegt. An diesem Punkt sei erwähnt dass wir über jede Spende sehr erfreut sind, am liebsten natürlich wenn sie regelmäßig ist. ;)
## Gerne, wo soll ich unterschreiben?
```
Empfänger: Chaostreff Dortmund e.V.
IBAN: DE19 4306 0967 4009 3686 00
BIC: GENODEM1GLS
```
Der Chaostreff Dortmund ist vom Finanzamt als gemeinnützig anerkannt und deshalb dürfen wir Spendenbescheinigungen ausstellen.
*Der Chaostreff sagt in jedem Fall schon mal Danke!*

20
pages/treff.md Normal file
View File

@ -0,0 +1,20 @@
# Der Treff
## Zeiten
Wir sind für gewöhnlich **Freitags ab 19:00** (±1hr Chaos-Verspätung) im Treff. Bevor du kommst schau einmal nach ob jemand da ist. Das kannst du oben beim Raumstatus sehen.
## Location
Die Räume sind im **Langen August**. Wenn du den Langen August gefunden hast, geh durch das erste Tor, dann findest du auf der rechten Seite eine Tür in das Treppenhaus. Da noch zwei Stockwerke hoch, die rechte Tür führt zu uns. Wenn die Türen verschlossen sind, einfach (beim Chaostreff) klingeln.
## Was wir tun
Von dem gemütlichen Beisammensitzen, über das Fachsimpeln von technischen Themen und das Diskutieren von aktuellen politischen Themen ist eigentlich alles dabei. Bei uns ist viel Raum für eigene Ideen und Projekte. Alle sind dazu eingeladen uns zu besuchen und sich einzubringen.
Wir freuen uns sehr über neue Gesichter, egal welchen Alters oder Geschlechts ihr seid. Spezielles Vorwissen über Computer und Technik ist nicht erforderlich.
Wir sind bemüht unsere Interessen in Projekten zu organisieren. Du bist herzlich eingeladen mal einen Blick auf diese zu werfen.
Einmal im Monat halten Leute im Chaostreff Vorträge über verschiedene Themen technischer und auch nichttechnischer Natur. Informationen darüber findest du unter Events.
Jeden ersten Donnerstag und jeden dritten Dienstag im Monat treffen wir uns zum „Topic Treff“ um verschiedene Themen rund um den Chaostreff zu besprechen. Alle sind herzlich eingeladen, Start ist um 20:00 Uhr.

33
pages/verein.md Normal file
View File

@ -0,0 +1,33 @@
# Mitglied werden
Durch deine Mitgliedschaft kannst du dem CTDO direkt deine Unterstützung zukommen lassen. Wenn du uns zu deiner Mitgliedschaft einen freiwilligen Betrag spendest, wird dieser für neue Projekte und die Umsetzung von tollen Ideen verwendet.
Du kannst den Mitgliedsantrag [hier](https://www.chaostreff-dortmund.de/wp-content/uploads/2011/07/mitgliedsantrag-2017.pdf) herunterladen, ausfüllen, und zum Chaostreff mitbringen.
Selbstverständlich kannst du auch im Chaostreff-Dortmund aktiv sein, ohne Mitglied in unserem Verein zu sein. Es erfolgt keine Bestätigung über die Annahme des Mitgliedsantrages. Im Falle einer Ablehnung erfolgt eine Mitteilung.
## Satzung
Die aktuelle Satzung des Vereins Chaostreff Dortmund e.V. kann stets hier auf unserer Webseite heruntergeladen werden. Darin eventuell referenzierte Anhänge oder Zusatzvereinbarungen, die nicht notwendigerweise Teil der Satzung selbst sind, sind jeweils der Einfachheit halber als ein PDF-Dokument direkt der aktuellen Satzung anhängig.
[Aktuelle Satzung](https://www.chaostreff-dortmund.de/presse/satzung/aktuelle_satzung.pdf)
[Alle Satzungen](https://www.chaostreff-dortmund.de/presse/satzung/)
## Gründungsgeschichte
Der Verein wurde als „Trägerverein“ des Chaostreffs im Jahre 2009 gegründet um dem Chaostreff als losen Verbund von Menschen gleicher Interessen eine (solide) rechtliche Grundlage zu geben.
Der Wechsel zur Rechtsform des eingetragenen Vereins sollte verschiedene Haftungsprobleme, vor allem finanzieller und mietrechtlicher Natur, aus der Welt schaffen. So lief der Mietvertrag für die Räume des Chaostreffs ursprünglich über eine Einzelperson, ebenso wie die jeweilige Kassenverwaltung die Finanzen über ein privates Konto führte.
Erste Diskussionen über den Sinn der Gründung eines Vereins gab es bereits im Jahre 2007, der Prozess kam aber immer wieder zum Stillstand und wurde erst 2009 wieder aufgenommen.
Die Gründung gestaltete sich auch deswegen so schwierig, weil unter den Mitgliedern/Besuchenden des Chaostreffs verschiedene Strömungen existierten, deren Standpunkte zur Vereinsgründung unterschiedlicher nicht sein konnten, woraufhin sich manch eine Person gar vollständig aus dem Chaostreff zurückzog.
Der Chaostreff teilte sich grob in zwei Lager, von denen das eine die Gründung eines Vereins (u.a. in Furcht vor Vereinsmeierei) vollständig ablehnte. Wohl auch teilweise zu Recht, weil es die Befürchtung gab, dass der Verein unerwünschten Einfluss auf das Konstrukt „Chaostreff“ ausüben könnte, der bis dahin selbstverwaltet, oder etwas überspitzt ausgedrückt, „anarchisch“ daherkam. Das andere Lager betrachtete die Vereinsgründung hingegen als „notwendiges Übel“, weil sich in Sachen Rechtssicherheit keine Alternative offenbarte.
Nach der Gründungsversammlung existierte der CTDO längere Zeit als eingetragener Verein „iG“ (in Gründung). Es folgte eine mehrfache Überarbeitung der Satzung, was im wesentlichen der Zusammenarbeit mit dem Finanzamt geschuldet war, in dem Bemühen, als gemeinnützig anerkannt zu werden. 2011-08-05 lag die Satzung schließlich dem Notar vor.
Doch durch Umzüge von einigen Gründungsmitgliedern verzögerte sich die Eintragung weiterhin, da noch Unterschriften (u.a. aus dem Ausland) von eben diesen Mitgliedern organisiert werden mussten.
Schließlich haben wir es aber geschafft: 2012-02-09 kann als Datum gesehen werden, ab dem sich der Chaostreff Dortmund als eingetragener Verein bezeichnen darf. Einen weiteren Meilenstein erreichten wir etwas später: Das Finanzamt stellte uns die Anerkennung der Gemeinnützigkeit in Aussicht, zu der es noch einer Änderung in der Satzung bedurfte.

129
php/events.php Normal file
View File

@ -0,0 +1,129 @@
<?php
function scan_for_events() {
$s = scandir(__DIR__ . '/../events/', SCANDIR_SORT_DESCENDING);
$output = array();
foreach ($s as $f) {
if(count(str_split($f)) >= 4 && $f != 'treff.md' && $f != 'topictreff.md' && $f != 'repaircafe.md' && $f != 'brunch.md')
$output[] = $f;
}
return $output;
}
function generate_event_list($limit = -1) {
$events = scan_for_events();
$output = "";
if ($limit == -1) {
foreach ($events as $event) {
$lines = file(__DIR__ . '/../events/' . $event);
$title = $lines[0];
$desc = $lines[1];
$date = $lines[2];
$veranstaltungsort = $lines[4];
$output .= '<div class="eventblock"><a href="?page=events&id='.str_replace('.md', '', $event).'"><h3 class="a">'.$veranstaltungsort.'</h3><h3 class="b">'.$date.'</h3><h2>'.$title.'</h2><p>'.$desc.'</p></a></div>';
}
} else {
if($limit > count($events))
$limit = count($events);
for ($i = 0; $i < $limit; $i++) {
$lines = file(__DIR__ . '/../events/' . $event);
$title = $lines[0];
$desc = $lines[1];
$date = $lines[2];
$veranstaltungsort = $lines[4];
$output .= '<div class="eventblock"><a href="?page=events&id='.str_replace('.md', '', $event).'"><h3 class="a">'.$veranstaltungsort.'</h3><h3 class="b">'.$date.'</h3><h2>'.$title.'</h2><p>'.$desc.'</p></a></div>';
}
}
return $output;
}
function get_event_content($id) {
$lines = file(__DIR__ . '/../events/' . str_replace('.', '', $id) . '.md');
$output = "";
$output .= '## Datum/Zeit'."\n\n";
$output .= $lines[2]."\n".$lines[3]."\n\n## Veranstaltungsort\n\n".$lines[4]."\n\n";
for ($i = 6; $i < count($lines); $i++)
$output .= $lines[$i] . "\n";
return $output;
}
function get_next_topic() {
$output = new stdClass();
$currentDate = new DateTime();
$next_topic = clone $currentDate;
$next_topic->modify('second Tuesday of this month +1 week');
while ($next_topic->format('N') !== '2') {
$next_topic->add(new DateInterval('P1D'));
}
$output->days = $currentDate->diff($next_topic)->days+1;
$output->date = $next_topic->format('Y-m-d');
return $output;
}
function get_next_treff() {
$output = new stdClass();
// Get current date and time
$now = new DateTime();
// Find the next Friday
$now->modify('next Friday');
// Calculate the number of days until the next Friday
$diff = $now->diff(new DateTime());
$days_until = $diff->format('%a');
$output->days = $days_until+1;
$output->date = $now->format('Y-m-d');
// Return an array with the count and date of the next Friday
return $output;
}
function get_next_repaircafe() {
$output = new stdClass();
$today = new DateTime();
$lastDayOfMonth = clone $today;
$lastDayOfMonth->modify('last day of this month');
$lastThursday = clone $lastDayOfMonth;
while ($lastThursday->format('w') != 4) { // Thursday is represented by 4 (0-6, where 0 is Sunday)
$lastThursday->modify('-1 day');
}
$daysUntilLastThursday = $today->diff($lastThursday)->days;
$output->days = $daysUntilLastThursday;
$output->date = $lastThursday->format('Y-m-d');
return $output;
}
function get_next_brunch() {
$now = new DateTime();
if ($now->format('w') == 0) {
$nextSunday = clone $now;
} else {
$nextSunday = new DateTime('next Sunday');
}
$weekNumber = (int)$nextSunday->format('W');
$isEvenWeek = ($weekNumber % 2) == 0;
if ($isEvenWeek) {
$nextSunday->modify('+1 week');
}
$differenz = $nextSunday->diff($now);
$days = $differenz->days;
$output = new stdClass();
$output->date = $nextSunday->format('Y-m-d');
$output->days = $days+1;
return $output;
}
?>

48
php/posts.php Normal file
View File

@ -0,0 +1,48 @@
<?php
function scan_for_posts() {
$s = scandir(__DIR__ . '/../posts/', SCANDIR_SORT_DESCENDING);
$output = array();
foreach ($s as $f) {
if(count(str_split($f)) >= 4)
$output[] = $f;
}
return $output;
}
function generate_post_list($limit = -1) {
$events = scan_for_posts();
$output = "";
if ($limit == -1) {
foreach ($events as $event) {
$lines = file(__DIR__ . '/../posts/' . $event);
$title = $lines[0];
$desc = $lines[1];
$date = $lines[2];
$signatur = $lines[3];
$output .= '<div class="eventblock"><h3>'.$signatur.'<br>'.$date.'</h3><a href="?page=blog&id='.str_replace('.md', '', $event).'"><h2>'.$title.'</h2><p>'.$desc.'</p></a></div>';
}
} else {
if($limit > count($events))
$limit = count($events);
for ($i = 0; $i < $limit; $i++) {
$lines = file(__DIR__ . '/../posts/' . $events[$i]);
$title = $lines[0];
$desc = $lines[1];
$date = $lines[2];
$signatur = $lines[3];
$output .= '<div class="eventblock"><h3 class="a">'.$signatur.'</h3><h3 class="b">'.$date.'</h3><a href="?page=blog&id='.str_replace('.md', '', $events[$i]).'"><h2>'.$title.'</h2><p>'.$desc.'</p></a></div>';
}
}
return $output;
}
function get_post_content($id) {
$lines = file(__DIR__ . '/../posts/' . str_replace('.', '', $id) . '.md');
$output = "";
for ($i = 5; $i < count($lines); $i++)
$output .= $lines[$i] . "\n";
return $output;
}
?>

38
php/util.php Normal file
View File

@ -0,0 +1,38 @@
<?php
function css_link($src) {
return '<link rel="stylesheet" href="'.$src.'">';
}
function generate_nav($active_page, $pages, $page_names) {
$output = array();
foreach ($pages as $key => $page) {
if ($page == $active_page)
$output[] = ['page' => $page, 'name' => $page_names[$key], 'active' => TRUE];
else
$output[] = ['page' => $page, 'name' => $page_names[$key], 'active' => FALSE];
}
return $output;
}
function html_link($href, $class, $innerHTML, $blank) {
if($blank)
return '<a href="'.$href.'" class="'.$class.'" target="_blank">'.$innerHTML.'</a>';
else
return '<a href="'.$href.'" class="'.$class.'">'.$innerHTML.'</a>';
}
function get_web_json($url) {
$data = json_decode(file_get_contents($url), true);
return $data;
}
function str_mass_replace($searchs, $replacers, $string) {
foreach ($searchs as $key => $search) {
$string = str_replace($search, $replacers[$key], $string);
}
return $string;
}
?>

14
posts/0.md Normal file
View File

@ -0,0 +1,14 @@
ChaosBrunch am Sonntag, 02.04.2023
Alle zwei Wochen an einem Sonntag lädt der CTDO zum Mitbring-Brunch in seinen Räume im Kulturzentrum „Langer August“ ein!
2023-05-01
starcalc
------------------------
# ChaosBrunch am Sonntag, 02.04.2023
Alle zwei Wochen an einem Sonntag lädt der CTDO zum **Mitbring-Brunch** in seinen Räume im Kulturzentrum „[Langer August](/?page=treff)“ ein!
Um **ca. 11 Uhr** geht es los, das Ende ist wie immer offen. Die Details dazu gibt es im [ctdo wiki](https://wiki.ctdo.de/events/hackerbrunch)!
Schaut einfach vorab im (MitbringPad)[https://md.ctdo.de/brunch] rein und kündigt an was ihr auf den Tisch werft, alles kann, nichts muss!
Es sind sowohl alte als auch neue Menschen gerne gesehen! Bringt was zu futtern, euer aktuelles Projekt, beides oder einfach nur Neugierde mit!

14
posts/1.md Normal file
View File

@ -0,0 +1,14 @@
Bunt, Bunter, Chaostreff Dortmund
Wir öffnen unsere Türen und laden Euch herzlich in unseren Chaostreff im Langen August ein.
2023-05-02
Fisch
------------------------
# Bunt, Bunter, Chaostreff Dortmundchten
![DORTBUND](/images/events/DORTBUNT.nebenan_Banner-fuer-Anmeldende-768x154.png)
Wir öffnen unsere Türen und laden Euch herzlich in unseren Chaostreff im [Langen August](/?page=treff) ein.
Am 5. und 6. Mai zwischen 14 und 20 Uhr könnt ihr einfach vorbeikommen und erhaltet einen Einblick in unseren Space, unsere Vereinsräume mitsamt allen Werkstätten. Um das ganze netter zu gestalten, gibt es kalte Getränke, Waffeln und auch der Grill wird angemacht.
Wir freuen uns auf Euch, egal ob jung, alt, groß, klein, laut oder leise. Hauptsache bunt!

1
templates/404.twig Normal file
View File

@ -0,0 +1 @@
<h2>404 Die Seite "{{ page }}" konnte nicht gefunden werden!</h2>

2
templates/blog.twig Normal file
View File

@ -0,0 +1,2 @@
<h1>Blog</h1>
{{ posts | raw }}

54
templates/default.twig Normal file
View File

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ctdo - {{ title }}</title>
{% for item in css %}
<link rel="stylesheet" href="/css/{{ item }}.css">
{% endfor %}
</head>
<body>
<!-- <div class="newBanner"><a href="https://www.chaostreff-dortmund.de/rundgang/" target="_blank">Rundgang</a></div> -->
<header>
<a onclick="ToggleNav()" id="navToggle">=</a>
<nav>
<ul>
{% for item in nav %}
<li>
{% if item.active %}
<a href="?page={{ item.page }}" class="active">{{ item.name }}</a>
{% else %}
<a href="?page={{ item.page }}">{{ item.name }}</a>
{% endif %}
</li>
{% endfor %}
</ul>
</nav>
</header>
<main>
<p class="text-left">Raumstatus: {{ raumstatus | raw }}</p>
{{ main | raw }}
</main>
<footer>
<nav>
<ul>
<li> <a href="/?page=impressum">impressum</a> </li>
<li> <a href="/?page=datenschutz">datenschutz</a> </li>
<li> <a href="https://git.ctdo.de/xoy/ctdo.de/_edit/main/{{ file_to_edit }}" target="_blank">seite bearbeiten</a> </li>
</ul>
</nav>
</footer>
<script src="js/nav.js"></script>
</body>
</html>

35
templates/events.twig Normal file
View File

@ -0,0 +1,35 @@
<h1>Events</h1>
{% if topic.days == 0 %}
<p class="topic">Der nächste <a href="/?page=events&id=topictreff">Topictreff</a> findet heute [{{ topic.date }}] statt!</p>
{% elseif topic.days == 1 %}
<p class="topic">Der nächste <a href="/?page=events&id=topictreff">Topictreff</a> findet morgen [{{ topic.date }}] statt!</p>
{% else %}
<p class="topic">Der nächste <a href="/?page=events&id=topictreff">Topictreff</a> findet in {{ topic.days }} Tagen [{{ topic.date }}] statt!</p>
{% endif %}
{% if treff.days == 0 %}
<p class="topic">Der nächste <a href="/?page=events&id=treff">Treff</a> findet heute [{{ treff.date }}] statt!</p>
{% elseif treff.days == 1 %}
<p class="topic">Der nächste <a href="/?page=events&id=treff">Treff</a> findet morgen [{{ treff.date }}] statt!</p>
{% else %}
<p class="topic">Der nächste <a href="/?page=events&id=treff">Treff</a> findet in {{ treff.days }} Tagen [{{ treff.date }}] statt!</p>
{% endif %}
{% if repaircafe.days == 0 %}
<p class="topic">Das nächste <a href="/?page=events&id=repaircafe">RepairCafe</a> findet heute [{{ repaircafe.date }}] statt!</p>
{% elseif repaircafe.days == 1 %}
<p class="topic">Das nächste <a href="/?page=events&id=repaircafe">RepairCafe</a> findet morgen [{{ repaircafe.date }}] statt!</p>
{% else %}
<p class="topic">Das nächste <a href="/?page=events&id=repaircafe">RepairCafe</a> findet in Tagen {{ repaircafe.days }} [{{ repaircafe.date }}] statt!</p>
{% endif %}
{% if brunch.days == 0 %}
<p class="topic">Der nächste <a href="/?page=events&id=brunch">Brunch</a> findet heute [{{ brunch.date }}] statt!</p>
{% elseif brunch.days == 1 %}
<p class="topic">Der nächste <a href="/?page=events&id=brunch">Brunch</a> findet morgen [{{ brunch.date }}] statt!</p>
{% else %}
<p class="topic">Der nächste <a href="/?page=events&id=brunch">Brunch</a> findet in {{ brunch.days }} Tagen [{{ brunch.date }}] statt!</p>
{% endif %}
{{ events | raw }}

37
templates/index.twig Normal file
View File

@ -0,0 +1,37 @@
{{ content | raw }}
<h2>Die nächsten Events:</h2>
{% if topic.days == 0 %}
<p class="topic">Der nächste <a href="/?page=events&id=topictreff">Topictreff</a> findet heute [{{ topic.date }}] statt!</p>
{% elseif topic.days == 1 %}
<p class="topic">Der nächste <a href="/?page=events&id=topictreff">Topictreff</a> findet morgen [{{ topic.date }}] statt!</p>
{% else %}
<p class="topic">Der nächste <a href="/?page=events&id=topictreff">Topictreff</a> findet in {{ topic.days }} Tagen [{{ topic.date }}] statt!</p>
{% endif %}
{% if treff.days == 0 %}
<p class="topic">Der nächste <a href="/?page=events&id=treff">Treff</a> findet heute [{{ treff.date }}] statt!</p>
{% elseif treff.days == 1 %}
<p class="topic">Der nächste <a href="/?page=events&id=treff">Treff</a> findet morgen [{{ treff.date }}] statt!</p>
{% else %}
<p class="topic">Der nächste <a href="/?page=events&id=treff">Treff</a> findet in {{ treff.days }} Tagen [{{ treff.date }}] statt!</p>
{% endif %}
{% if repaircafe.days == 0 %}
<p class="topic">Das nächste <a href="/?page=events&id=repaircafe">RepairCafe</a> findet heute [{{ repaircafe.date }}] statt!</p>
{% elseif repaircafe.days == 1 %}
<p class="topic">Das nächste <a href="/?page=events&id=repaircafe">RepairCafe</a> findet morgen [{{ repaircafe.date }}] statt!</p>
{% else %}
<p class="topic">Das nächste <a href="/?page=events&id=repaircafe">RepairCafe</a> findet in Tagen {{ repaircafe.days }} [{{ repaircafe.date }}] statt!</p>
{% endif %}
{% if brunch.days == 0 %}
<p class="topic">Der nächste <a href="/?page=events&id=brunch">Brunch</a> findet heute [{{ brunch.date }}] statt!</p>
{% elseif brunch.days == 1 %}
<p class="topic">Der nächste <a href="/?page=events&id=brunch">Brunch</a> findet morgen [{{ brunch.date }}] statt!</p>
{% else %}
<p class="topic">Der nächste <a href="/?page=events&id=brunch">Brunch</a> findet in {{ brunch.days }} Tagen [{{ brunch.date }}] statt!</p>
{% endif %}
{{ events | raw }}

13
templates/kontakt.twig Normal file
View File

@ -0,0 +1,13 @@
<a href="?page=irc">
<img src="/images/chat_knopf.webp" alt="irc">
</a>
<a href="?page=mail">
<img src="/images/mail_knopf.webp" alt="email">
</a>
<br>
<a href="?page=tel">
<img src="/images/tel_knopf.webp" alt="tel">
</a>
<a href="?page=adresse">
<img src="/images/adresse_knopf.webp" alt="adresse">
</a>

25
vendor/autoload.php vendored Normal file
View File

@ -0,0 +1,25 @@
<?php
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitce41dc6e38789c9f43c485905030864d::getLoader();

585
vendor/composer/ClassLoader.php vendored Normal file
View File

@ -0,0 +1,585 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var ?string */
private $vendorDir;
// PSR-4
/**
* @var array[]
* @psalm-var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, array<int, string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* @var array[]
* @psalm-var array<string, array<string, string[]>>
*/
private $prefixesPsr0 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var string[]
* @psalm-var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var bool[]
* @psalm-var array<string, bool>
*/
private $missingClasses = array();
/** @var ?string */
private $apcuPrefix;
/**
* @var self[]
*/
private static $registeredLoaders = array();
/**
* @param ?string $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return string[]
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
/**
* @return array[]
* @psalm-return array<string, array<int, string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return string[] Array of classname => path
* @psalm-return array<string, string>
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
*
* @return void
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
return null;
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
/**
* Returns the currently registered loaders indexed by their corresponding vendor directories.
*
* @return self[]
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}

352
vendor/composer/InstalledVersions.php vendored Normal file
View File

@ -0,0 +1,352 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints($constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = require __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
$installed[] = self::$installed;
return $installed;
}
}

21
vendor/composer/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

72
vendor/composer/autoload_classmap.php vendored Normal file
View File

@ -0,0 +1,72 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'Nette\\ArgumentOutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\DeprecatedException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\DirectoryNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\FileNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\HtmlStringable' => $vendorDir . '/nette/utils/src/HtmlStringable.php',
'Nette\\IOException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\InvalidArgumentException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\InvalidStateException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\Iterators\\CachingIterator' => $vendorDir . '/nette/utils/src/Iterators/CachingIterator.php',
'Nette\\Iterators\\Mapper' => $vendorDir . '/nette/utils/src/Iterators/Mapper.php',
'Nette\\Localization\\ITranslator' => $vendorDir . '/nette/utils/src/compatibility.php',
'Nette\\Localization\\Translator' => $vendorDir . '/nette/utils/src/Translator.php',
'Nette\\MemberAccessException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\NotImplementedException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\NotSupportedException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\OutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\Schema\\Context' => $vendorDir . '/nette/schema/src/Schema/Context.php',
'Nette\\Schema\\DynamicParameter' => $vendorDir . '/nette/schema/src/Schema/DynamicParameter.php',
'Nette\\Schema\\Elements\\AnyOf' => $vendorDir . '/nette/schema/src/Schema/Elements/AnyOf.php',
'Nette\\Schema\\Elements\\Base' => $vendorDir . '/nette/schema/src/Schema/Elements/Base.php',
'Nette\\Schema\\Elements\\Structure' => $vendorDir . '/nette/schema/src/Schema/Elements/Structure.php',
'Nette\\Schema\\Elements\\Type' => $vendorDir . '/nette/schema/src/Schema/Elements/Type.php',
'Nette\\Schema\\Expect' => $vendorDir . '/nette/schema/src/Schema/Expect.php',
'Nette\\Schema\\Helpers' => $vendorDir . '/nette/schema/src/Schema/Helpers.php',
'Nette\\Schema\\Message' => $vendorDir . '/nette/schema/src/Schema/Message.php',
'Nette\\Schema\\Processor' => $vendorDir . '/nette/schema/src/Schema/Processor.php',
'Nette\\Schema\\Schema' => $vendorDir . '/nette/schema/src/Schema/Schema.php',
'Nette\\Schema\\ValidationException' => $vendorDir . '/nette/schema/src/Schema/ValidationException.php',
'Nette\\SmartObject' => $vendorDir . '/nette/utils/src/SmartObject.php',
'Nette\\StaticClass' => $vendorDir . '/nette/utils/src/StaticClass.php',
'Nette\\UnexpectedValueException' => $vendorDir . '/nette/utils/src/exceptions.php',
'Nette\\Utils\\ArrayHash' => $vendorDir . '/nette/utils/src/Utils/ArrayHash.php',
'Nette\\Utils\\ArrayList' => $vendorDir . '/nette/utils/src/Utils/ArrayList.php',
'Nette\\Utils\\Arrays' => $vendorDir . '/nette/utils/src/Utils/Arrays.php',
'Nette\\Utils\\AssertionException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php',
'Nette\\Utils\\Callback' => $vendorDir . '/nette/utils/src/Utils/Callback.php',
'Nette\\Utils\\DateTime' => $vendorDir . '/nette/utils/src/Utils/DateTime.php',
'Nette\\Utils\\FileInfo' => $vendorDir . '/nette/utils/src/Utils/FileInfo.php',
'Nette\\Utils\\FileSystem' => $vendorDir . '/nette/utils/src/Utils/FileSystem.php',
'Nette\\Utils\\Finder' => $vendorDir . '/nette/utils/src/Utils/Finder.php',
'Nette\\Utils\\Floats' => $vendorDir . '/nette/utils/src/Utils/Floats.php',
'Nette\\Utils\\Helpers' => $vendorDir . '/nette/utils/src/Utils/Helpers.php',
'Nette\\Utils\\Html' => $vendorDir . '/nette/utils/src/Utils/Html.php',
'Nette\\Utils\\IHtmlString' => $vendorDir . '/nette/utils/src/compatibility.php',
'Nette\\Utils\\Image' => $vendorDir . '/nette/utils/src/Utils/Image.php',
'Nette\\Utils\\ImageException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php',
'Nette\\Utils\\Json' => $vendorDir . '/nette/utils/src/Utils/Json.php',
'Nette\\Utils\\JsonException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php',
'Nette\\Utils\\ObjectHelpers' => $vendorDir . '/nette/utils/src/Utils/ObjectHelpers.php',
'Nette\\Utils\\Paginator' => $vendorDir . '/nette/utils/src/Utils/Paginator.php',
'Nette\\Utils\\Random' => $vendorDir . '/nette/utils/src/Utils/Random.php',
'Nette\\Utils\\Reflection' => $vendorDir . '/nette/utils/src/Utils/Reflection.php',
'Nette\\Utils\\RegexpException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php',
'Nette\\Utils\\Strings' => $vendorDir . '/nette/utils/src/Utils/Strings.php',
'Nette\\Utils\\Type' => $vendorDir . '/nette/utils/src/Utils/Type.php',
'Nette\\Utils\\UnknownImageFileException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php',
'Nette\\Utils\\Validators' => $vendorDir . '/nette/utils/src/Utils/Validators.php',
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
);

13
vendor/composer/autoload_files.php vendored Normal file
View File

@ -0,0 +1,13 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
);

View File

@ -0,0 +1,9 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
);

17
vendor/composer/autoload_psr4.php vendored Normal file
View File

@ -0,0 +1,17 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Twig\\' => array($vendorDir . '/twig/twig/src'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'),
'League\\Config\\' => array($vendorDir . '/league/config/src'),
'League\\CommonMark\\' => array($vendorDir . '/league/commonmark/src'),
'Dflydev\\DotAccessData\\' => array($vendorDir . '/dflydev/dot-access-data/src'),
);

50
vendor/composer/autoload_real.php vendored Normal file
View File

@ -0,0 +1,50 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitce41dc6e38789c9f43c485905030864d
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInitce41dc6e38789c9f43c485905030864d', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitce41dc6e38789c9f43c485905030864d', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitce41dc6e38789c9f43c485905030864d::getInitializer($loader));
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInitce41dc6e38789c9f43c485905030864d::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
}
return $loader;
}
}

152
vendor/composer/autoload_static.php vendored Normal file
View File

@ -0,0 +1,152 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInitce41dc6e38789c9f43c485905030864d
{
public static $files = array (
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
);
public static $prefixLengthsPsr4 = array (
'T' =>
array (
'Twig\\' => 5,
),
'S' =>
array (
'Symfony\\Polyfill\\Php80\\' => 23,
'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Polyfill\\Ctype\\' => 23,
),
'P' =>
array (
'Psr\\EventDispatcher\\' => 20,
),
'L' =>
array (
'League\\Config\\' => 14,
'League\\CommonMark\\' => 18,
),
'D' =>
array (
'Dflydev\\DotAccessData\\' => 22,
),
);
public static $prefixDirsPsr4 = array (
'Twig\\' =>
array (
0 => __DIR__ . '/..' . '/twig/twig/src',
),
'Symfony\\Polyfill\\Php80\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
),
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Polyfill\\Ctype\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
),
'Psr\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/psr/event-dispatcher/src',
),
'League\\Config\\' =>
array (
0 => __DIR__ . '/..' . '/league/config/src',
),
'League\\CommonMark\\' =>
array (
0 => __DIR__ . '/..' . '/league/commonmark/src',
),
'Dflydev\\DotAccessData\\' =>
array (
0 => __DIR__ . '/..' . '/dflydev/dot-access-data/src',
),
);
public static $classMap = array (
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'Nette\\ArgumentOutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\DeprecatedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\DirectoryNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\FileNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\HtmlStringable' => __DIR__ . '/..' . '/nette/utils/src/HtmlStringable.php',
'Nette\\IOException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\InvalidArgumentException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\InvalidStateException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\Iterators\\CachingIterator' => __DIR__ . '/..' . '/nette/utils/src/Iterators/CachingIterator.php',
'Nette\\Iterators\\Mapper' => __DIR__ . '/..' . '/nette/utils/src/Iterators/Mapper.php',
'Nette\\Localization\\ITranslator' => __DIR__ . '/..' . '/nette/utils/src/compatibility.php',
'Nette\\Localization\\Translator' => __DIR__ . '/..' . '/nette/utils/src/Translator.php',
'Nette\\MemberAccessException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\NotImplementedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\NotSupportedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\OutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\Schema\\Context' => __DIR__ . '/..' . '/nette/schema/src/Schema/Context.php',
'Nette\\Schema\\DynamicParameter' => __DIR__ . '/..' . '/nette/schema/src/Schema/DynamicParameter.php',
'Nette\\Schema\\Elements\\AnyOf' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/AnyOf.php',
'Nette\\Schema\\Elements\\Base' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/Base.php',
'Nette\\Schema\\Elements\\Structure' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/Structure.php',
'Nette\\Schema\\Elements\\Type' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/Type.php',
'Nette\\Schema\\Expect' => __DIR__ . '/..' . '/nette/schema/src/Schema/Expect.php',
'Nette\\Schema\\Helpers' => __DIR__ . '/..' . '/nette/schema/src/Schema/Helpers.php',
'Nette\\Schema\\Message' => __DIR__ . '/..' . '/nette/schema/src/Schema/Message.php',
'Nette\\Schema\\Processor' => __DIR__ . '/..' . '/nette/schema/src/Schema/Processor.php',
'Nette\\Schema\\Schema' => __DIR__ . '/..' . '/nette/schema/src/Schema/Schema.php',
'Nette\\Schema\\ValidationException' => __DIR__ . '/..' . '/nette/schema/src/Schema/ValidationException.php',
'Nette\\SmartObject' => __DIR__ . '/..' . '/nette/utils/src/SmartObject.php',
'Nette\\StaticClass' => __DIR__ . '/..' . '/nette/utils/src/StaticClass.php',
'Nette\\UnexpectedValueException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php',
'Nette\\Utils\\ArrayHash' => __DIR__ . '/..' . '/nette/utils/src/Utils/ArrayHash.php',
'Nette\\Utils\\ArrayList' => __DIR__ . '/..' . '/nette/utils/src/Utils/ArrayList.php',
'Nette\\Utils\\Arrays' => __DIR__ . '/..' . '/nette/utils/src/Utils/Arrays.php',
'Nette\\Utils\\AssertionException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php',
'Nette\\Utils\\Callback' => __DIR__ . '/..' . '/nette/utils/src/Utils/Callback.php',
'Nette\\Utils\\DateTime' => __DIR__ . '/..' . '/nette/utils/src/Utils/DateTime.php',
'Nette\\Utils\\FileInfo' => __DIR__ . '/..' . '/nette/utils/src/Utils/FileInfo.php',
'Nette\\Utils\\FileSystem' => __DIR__ . '/..' . '/nette/utils/src/Utils/FileSystem.php',
'Nette\\Utils\\Finder' => __DIR__ . '/..' . '/nette/utils/src/Utils/Finder.php',
'Nette\\Utils\\Floats' => __DIR__ . '/..' . '/nette/utils/src/Utils/Floats.php',
'Nette\\Utils\\Helpers' => __DIR__ . '/..' . '/nette/utils/src/Utils/Helpers.php',
'Nette\\Utils\\Html' => __DIR__ . '/..' . '/nette/utils/src/Utils/Html.php',
'Nette\\Utils\\IHtmlString' => __DIR__ . '/..' . '/nette/utils/src/compatibility.php',
'Nette\\Utils\\Image' => __DIR__ . '/..' . '/nette/utils/src/Utils/Image.php',
'Nette\\Utils\\ImageException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php',
'Nette\\Utils\\Json' => __DIR__ . '/..' . '/nette/utils/src/Utils/Json.php',
'Nette\\Utils\\JsonException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php',
'Nette\\Utils\\ObjectHelpers' => __DIR__ . '/..' . '/nette/utils/src/Utils/ObjectHelpers.php',
'Nette\\Utils\\Paginator' => __DIR__ . '/..' . '/nette/utils/src/Utils/Paginator.php',
'Nette\\Utils\\Random' => __DIR__ . '/..' . '/nette/utils/src/Utils/Random.php',
'Nette\\Utils\\Reflection' => __DIR__ . '/..' . '/nette/utils/src/Utils/Reflection.php',
'Nette\\Utils\\RegexpException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php',
'Nette\\Utils\\Strings' => __DIR__ . '/..' . '/nette/utils/src/Utils/Strings.php',
'Nette\\Utils\\Type' => __DIR__ . '/..' . '/nette/utils/src/Utils/Type.php',
'Nette\\Utils\\UnknownImageFileException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php',
'Nette\\Utils\\Validators' => __DIR__ . '/..' . '/nette/utils/src/Utils/Validators.php',
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitce41dc6e38789c9f43c485905030864d::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitce41dc6e38789c9f43c485905030864d::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitce41dc6e38789c9f43c485905030864d::$classMap;
}, null, ClassLoader::class);
}
}

892
vendor/composer/installed.json vendored Normal file
View File

@ -0,0 +1,892 @@
{
"packages": [
{
"name": "dflydev/dot-access-data",
"version": "v3.0.2",
"version_normalized": "3.0.2.0",
"source": {
"type": "git",
"url": "https://github.com/dflydev/dflydev-dot-access-data.git",
"reference": "f41715465d65213d644d3141a6a93081be5d3549"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549",
"reference": "f41715465d65213d644d3141a6a93081be5d3549",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.42",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.3",
"scrutinizer/ocular": "1.6.0",
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^4.0.0"
},
"time": "2022-10-27T11:44:00+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Dflydev\\DotAccessData\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dragonfly Development Inc.",
"email": "info@dflydev.com",
"homepage": "http://dflydev.com"
},
{
"name": "Beau Simensen",
"email": "beau@dflydev.com",
"homepage": "http://beausimensen.com"
},
{
"name": "Carlos Frutos",
"email": "carlos@kiwing.it",
"homepage": "https://github.com/cfrutos"
},
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com"
}
],
"description": "Given a deep data structure, access data by dot notation.",
"homepage": "https://github.com/dflydev/dflydev-dot-access-data",
"keywords": [
"access",
"data",
"dot",
"notation"
],
"support": {
"issues": "https://github.com/dflydev/dflydev-dot-access-data/issues",
"source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2"
},
"install-path": "../dflydev/dot-access-data"
},
{
"name": "league/commonmark",
"version": "2.4.0",
"version_normalized": "2.4.0.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d44a24690f16b8c1808bf13b1bd54ae4c63ea048",
"reference": "d44a24690f16b8c1808bf13b1bd54ae4c63ea048",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"league/config": "^1.1.1",
"php": "^7.4 || ^8.0",
"psr/event-dispatcher": "^1.0",
"symfony/deprecation-contracts": "^2.1 || ^3.0",
"symfony/polyfill-php80": "^1.16"
},
"require-dev": {
"cebe/markdown": "^1.0",
"commonmark/cmark": "0.30.0",
"commonmark/commonmark.js": "0.30.0",
"composer/package-versions-deprecated": "^1.8",
"embed/embed": "^4.4",
"erusev/parsedown": "^1.0",
"ext-json": "*",
"github/gfm": "0.29.0",
"michelf/php-markdown": "^1.4 || ^2.0",
"nyholm/psr7": "^1.5",
"phpstan/phpstan": "^1.8.2",
"phpunit/phpunit": "^9.5.21",
"scrutinizer/ocular": "^1.8.1",
"symfony/finder": "^5.3 | ^6.0",
"symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0",
"unleashedtech/php-coding-standard": "^3.1.1",
"vimeo/psalm": "^4.24.0 || ^5.0.0"
},
"suggest": {
"symfony/yaml": "v2.3+ required if using the Front Matter extension"
},
"time": "2023-03-24T15:16:10+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.5-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"League\\CommonMark\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com",
"role": "Lead Developer"
}
],
"description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)",
"homepage": "https://commonmark.thephpleague.com",
"keywords": [
"commonmark",
"flavored",
"gfm",
"github",
"github-flavored",
"markdown",
"md",
"parser"
],
"support": {
"docs": "https://commonmark.thephpleague.com/",
"forum": "https://github.com/thephpleague/commonmark/discussions",
"issues": "https://github.com/thephpleague/commonmark/issues",
"rss": "https://github.com/thephpleague/commonmark/releases.atom",
"source": "https://github.com/thephpleague/commonmark"
},
"funding": [
{
"url": "https://www.colinodell.com/sponsor",
"type": "custom"
},
{
"url": "https://www.paypal.me/colinpodell/10.00",
"type": "custom"
},
{
"url": "https://github.com/colinodell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/league/commonmark",
"type": "tidelift"
}
],
"install-path": "../league/commonmark"
},
{
"name": "league/config",
"version": "v1.2.0",
"version_normalized": "1.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/config.git",
"reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
"reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
"shasum": ""
},
"require": {
"dflydev/dot-access-data": "^3.0.1",
"nette/schema": "^1.2",
"php": "^7.4 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^1.8.2",
"phpunit/phpunit": "^9.5.5",
"scrutinizer/ocular": "^1.8.1",
"unleashedtech/php-coding-standard": "^3.1",
"vimeo/psalm": "^4.7.3"
},
"time": "2022-12-11T20:36:23+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.2-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"League\\Config\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com",
"role": "Lead Developer"
}
],
"description": "Define configuration arrays with strict schemas and access values with dot notation",
"homepage": "https://config.thephpleague.com",
"keywords": [
"array",
"config",
"configuration",
"dot",
"dot-access",
"nested",
"schema"
],
"support": {
"docs": "https://config.thephpleague.com/",
"issues": "https://github.com/thephpleague/config/issues",
"rss": "https://github.com/thephpleague/config/releases.atom",
"source": "https://github.com/thephpleague/config"
},
"funding": [
{
"url": "https://www.colinodell.com/sponsor",
"type": "custom"
},
{
"url": "https://www.paypal.me/colinpodell/10.00",
"type": "custom"
},
{
"url": "https://github.com/colinodell",
"type": "github"
}
],
"install-path": "../league/config"
},
{
"name": "nette/schema",
"version": "v1.2.3",
"version_normalized": "1.2.3.0",
"source": {
"type": "git",
"url": "https://github.com/nette/schema.git",
"reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/schema/zipball/abbdbb70e0245d5f3bf77874cea1dfb0c930d06f",
"reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f",
"shasum": ""
},
"require": {
"nette/utils": "^2.5.7 || ^3.1.5 || ^4.0",
"php": ">=7.1 <8.3"
},
"require-dev": {
"nette/tester": "^2.3 || ^2.4",
"phpstan/phpstan-nette": "^1.0",
"tracy/tracy": "^2.7"
},
"time": "2022-10-13T01:24:26+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
}
},
"installation-source": "dist",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause",
"GPL-2.0-only",
"GPL-3.0-only"
],
"authors": [
{
"name": "David Grudl",
"homepage": "https://davidgrudl.com"
},
{
"name": "Nette Community",
"homepage": "https://nette.org/contributors"
}
],
"description": "📐 Nette Schema: validating data structures against a given Schema.",
"homepage": "https://nette.org",
"keywords": [
"config",
"nette"
],
"support": {
"issues": "https://github.com/nette/schema/issues",
"source": "https://github.com/nette/schema/tree/v1.2.3"
},
"install-path": "../nette/schema"
},
{
"name": "nette/utils",
"version": "v4.0.0",
"version_normalized": "4.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
"reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/utils/zipball/cacdbf5a91a657ede665c541eda28941d4b09c1e",
"reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e",
"shasum": ""
},
"require": {
"php": ">=8.0 <8.3"
},
"conflict": {
"nette/finder": "<3",
"nette/schema": "<1.2.2"
},
"require-dev": {
"jetbrains/phpstorm-attributes": "dev-master",
"nette/tester": "^2.4",
"phpstan/phpstan": "^1.0",
"tracy/tracy": "^2.9"
},
"suggest": {
"ext-gd": "to use Image",
"ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()",
"ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()",
"ext-json": "to use Nette\\Utils\\Json",
"ext-mbstring": "to use Strings::lower() etc...",
"ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()",
"ext-xml": "to use Strings::length() etc. when mbstring is not available"
},
"time": "2023-02-02T10:41:53+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0-dev"
}
},
"installation-source": "dist",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause",
"GPL-2.0-only",
"GPL-3.0-only"
],
"authors": [
{
"name": "David Grudl",
"homepage": "https://davidgrudl.com"
},
{
"name": "Nette Community",
"homepage": "https://nette.org/contributors"
}
],
"description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.",
"homepage": "https://nette.org",
"keywords": [
"array",
"core",
"datetime",
"images",
"json",
"nette",
"paginator",
"password",
"slugify",
"string",
"unicode",
"utf-8",
"utility",
"validation"
],
"support": {
"issues": "https://github.com/nette/utils/issues",
"source": "https://github.com/nette/utils/tree/v4.0.0"
},
"install-path": "../nette/utils"
},
{
"name": "psr/event-dispatcher",
"version": "1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/event-dispatcher.git",
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
"shasum": ""
},
"require": {
"php": ">=7.2.0"
},
"time": "2019-01-08T18:20:26+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Psr\\EventDispatcher\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Standard interfaces for event handling.",
"keywords": [
"events",
"psr",
"psr-14"
],
"support": {
"issues": "https://github.com/php-fig/event-dispatcher/issues",
"source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
},
"install-path": "../psr/event-dispatcher"
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.2.1",
"version_normalized": "3.2.1.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
"reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
"shasum": ""
},
"require": {
"php": ">=8.1"
},
"time": "2023-03-01T10:25:55+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.3-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.1"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"install-path": "../symfony/deprecation-contracts"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.27.0",
"version_normalized": "1.27.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-ctype": "*"
},
"suggest": {
"ext-ctype": "For best performance"
},
"time": "2022-11-03T14:55:06+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"install-path": "../symfony/polyfill-ctype"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.27.0",
"version_normalized": "1.27.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
"reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-mbstring": "*"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"time": "2022-11-03T14:55:06+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"install-path": "../symfony/polyfill-mbstring"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.27.0",
"version_normalized": "1.27.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"time": "2022-11-03T14:55:06+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ion Bazan",
"email": "ion.bazan@gmail.com"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"install-path": "../symfony/polyfill-php80"
},
{
"name": "twig/twig",
"version": "v3.5.1",
"version_normalized": "3.5.1.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "a6e0510cc793912b451fd40ab983a1d28f611c15"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a6e0510cc793912b451fd40ab983a1d28f611c15",
"reference": "a6e0510cc793912b451fd40ab983a1d28f611c15",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3"
},
"require-dev": {
"psr/container": "^1.0",
"symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0"
},
"time": "2023-02-08T07:49:20+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.5-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Twig\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Twig Team",
"role": "Contributors"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com",
"role": "Project Founder"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "https://twig.symfony.com",
"keywords": [
"templating"
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
"source": "https://github.com/twigphp/Twig/tree/v3.5.1"
},
"funding": [
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
"type": "tidelift"
}
],
"install-path": "../twig/twig"
}
],
"dev": true,
"dev-package-names": []
}

122
vendor/composer/installed.php vendored Normal file
View File

@ -0,0 +1,122 @@
<?php return array(
'root' => array(
'name' => '__root__',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '29984ad7d3ad42a4ed8e223bd715d77685c1a699',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => true,
),
'versions' => array(
'__root__' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '29984ad7d3ad42a4ed8e223bd715d77685c1a699',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'dflydev/dot-access-data' => array(
'pretty_version' => 'v3.0.2',
'version' => '3.0.2.0',
'reference' => 'f41715465d65213d644d3141a6a93081be5d3549',
'type' => 'library',
'install_path' => __DIR__ . '/../dflydev/dot-access-data',
'aliases' => array(),
'dev_requirement' => false,
),
'league/commonmark' => array(
'pretty_version' => '2.4.0',
'version' => '2.4.0.0',
'reference' => 'd44a24690f16b8c1808bf13b1bd54ae4c63ea048',
'type' => 'library',
'install_path' => __DIR__ . '/../league/commonmark',
'aliases' => array(),
'dev_requirement' => false,
),
'league/config' => array(
'pretty_version' => 'v1.2.0',
'version' => '1.2.0.0',
'reference' => '754b3604fb2984c71f4af4a9cbe7b57f346ec1f3',
'type' => 'library',
'install_path' => __DIR__ . '/../league/config',
'aliases' => array(),
'dev_requirement' => false,
),
'nette/schema' => array(
'pretty_version' => 'v1.2.3',
'version' => '1.2.3.0',
'reference' => 'abbdbb70e0245d5f3bf77874cea1dfb0c930d06f',
'type' => 'library',
'install_path' => __DIR__ . '/../nette/schema',
'aliases' => array(),
'dev_requirement' => false,
),
'nette/utils' => array(
'pretty_version' => 'v4.0.0',
'version' => '4.0.0.0',
'reference' => 'cacdbf5a91a657ede665c541eda28941d4b09c1e',
'type' => 'library',
'install_path' => __DIR__ . '/../nette/utils',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/event-dispatcher' => array(
'pretty_version' => '1.0.0',
'version' => '1.0.0.0',
'reference' => 'dbefd12671e8a14ec7f180cab83036ed26714bb0',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/event-dispatcher',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/deprecation-contracts' => array(
'pretty_version' => 'v3.2.1',
'version' => '3.2.1.0',
'reference' => 'e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-ctype' => array(
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'reference' => '5bbc823adecdae860bb64756d639ecfec17b050a',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php80' => array(
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
'aliases' => array(),
'dev_requirement' => false,
),
'twig/twig' => array(
'pretty_version' => 'v3.5.1',
'version' => '3.5.1.0',
'reference' => 'a6e0510cc793912b451fd40ab983a1d28f611c15',
'type' => 'library',
'install_path' => __DIR__ . '/../twig/twig',
'aliases' => array(),
'dev_requirement' => false,
),
),
);

26
vendor/composer/platform_check.php vendored Normal file
View File

@ -0,0 +1,26 @@
<?php
// platform_check.php @generated by Composer
$issues = array();
if (!(PHP_VERSION_ID >= 80100)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.';
}
if ($issues) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
} elseif (!headers_sent()) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
trigger_error(
'Composer detected issues in your platform: ' . implode(' ', $issues),
E_USER_ERROR
);
}

View File

@ -0,0 +1,67 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [3.0.2] - 2022-10-27
### Fixed
- Added missing return types to docblocks (#44, #45)
## [3.0.1] - 2021-08-13
### Added
- Adds ReturnTypeWillChange to suppress PHP 8.1 warnings (#40)
## [3.0.0] - 2021-01-01
### Added
- Added support for both `.` and `/`-delimited key paths (#24)
- Added parameter and return types to everything; enabled strict type checks (#18)
- Added new exception classes to better identify certain types of errors (#20)
- `Data` now implements `ArrayAccess` (#17)
- Added ability to merge non-associative array values (#31, #32)
### Changed
- All thrown exceptions are now instances or subclasses of `DataException` (#20)
- Calling `get()` on a missing key path without providing a default will throw a `MissingPathException` instead of returning `null` (#29)
- Bumped supported PHP versions to 7.1 - 8.x (#18)
### Fixed
- Fixed incorrect merging of array values into string values (#32)
- Fixed `get()` method behaving as if keys with `null` values didn't exist
## [2.0.0] - 2017-12-21
### Changed
- Bumped supported PHP versions to 7.0 - 7.4 (#12)
- Switched to PSR-4 autoloading
## [1.1.0] - 2017-01-20
### Added
- Added new `has()` method to check for the existence of the given key (#4, #7)
## [1.0.1] - 2015-08-12
### Added
- Added new optional `$default` parameter to the `get()` method (#2)
## [1.0.0] - 2012-07-17
**Initial release!**
[Unreleased]: https://github.com/dflydev/dflydev-dot-access-data/compare/v3.0.2...main
[3.0.2]: https://github.com/dflydev/dflydev-dot-access-data/compare/v3.0.1...v3.0.2
[3.0.1]: https://github.com/dflydev/dflydev-dot-access-data/compare/v3.0.0...v3.0.1
[3.0.0]: https://github.com/dflydev/dflydev-dot-access-data/compare/v2.0.0...v3.0.0
[2.0.0]: https://github.com/dflydev/dflydev-dot-access-data/compare/v1.1.0...v2.0.0
[1.1.0]: https://github.com/dflydev/dflydev-dot-access-data/compare/v1.0.1...v1.1.0
[1.0.1]: https://github.com/dflydev/dflydev-dot-access-data/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.com/dflydev/dflydev-dot-access-data/releases/tag/v1.0.0

19
vendor/dflydev/dot-access-data/LICENSE vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2012 Dragonfly Development Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

158
vendor/dflydev/dot-access-data/README.md vendored Normal file
View File

@ -0,0 +1,158 @@
Dot Access Data
===============
[![Latest Version](https://img.shields.io/packagist/v/dflydev/dot-access-data.svg?style=flat-square)](https://packagist.org/packages/dflydev/dot-access-data)
[![Total Downloads](https://img.shields.io/packagist/dt/dflydev/dot-access-data.svg?style=flat-square)](https://packagist.org/packages/dflydev/dot-access-data)
[![Software License](https://img.shields.io/badge/License-MIT-brightgreen.svg?style=flat-square)](LICENSE)
[![Build Status](https://img.shields.io/github/workflow/status/dflydev/dflydev-dot-access-data/Tests/main.svg?style=flat-square)](https://github.com/dflydev/dflydev-dot-access-data/actions?query=workflow%3ATests+branch%3Amain)
[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/dflydev/dflydev-dot-access-data.svg?style=flat-square)](https://scrutinizer-ci.com/g/dflydev/dflydev-dot-access-data/code-structure/)
[![Quality Score](https://img.shields.io/scrutinizer/g/dflydev/dflydev-dot-access-data.svg?style=flat-square)](https://scrutinizer-ci.com/g/dflydev/dflydev-dot-access-data)
Given a deep data structure, access data by dot notation.
Requirements
------------
* PHP (7.1+)
> For PHP (5.3+) please refer to version `1.0`.
Usage
-----
Abstract example:
```php
use Dflydev\DotAccessData\Data;
$data = new Data;
$data->set('a.b.c', 'C');
$data->set('a.b.d', 'D1');
$data->append('a.b.d', 'D2');
$data->set('a.b.e', ['E0', 'E1', 'E2']);
// C
$data->get('a.b.c');
// ['D1', 'D2']
$data->get('a.b.d');
// ['E0', 'E1', 'E2']
$data->get('a.b.e');
// true
$data->has('a.b.c');
// false
$data->has('a.b.d.j');
// 'some-default-value'
$data->get('some.path.that.does.not.exist', 'some-default-value');
// throws a MissingPathException because no default was given
$data->get('some.path.that.does.not.exist');
```
A more concrete example:
```php
use Dflydev\DotAccessData\Data;
$data = new Data([
'hosts' => [
'hewey' => [
'username' => 'hman',
'password' => 'HPASS',
'roles' => ['web'],
],
'dewey' => [
'username' => 'dman',
'password' => 'D---S',
'roles' => ['web', 'db'],
'nick' => 'dewey dman',
],
'lewey' => [
'username' => 'lman',
'password' => 'LP@$$',
'roles' => ['db'],
],
],
]);
// hman
$username = $data->get('hosts.hewey.username');
// HPASS
$password = $data->get('hosts.hewey.password');
// ['web']
$roles = $data->get('hosts.hewey.roles');
// dewey dman
$nick = $data->get('hosts.dewey.nick');
// Unknown
$nick = $data->get('hosts.lewey.nick', 'Unknown');
// DataInterface instance
$dewey = $data->getData('hosts.dewey');
// dman
$username = $dewey->get('username');
// D---S
$password = $dewey->get('password');
// ['web', 'db']
$roles = $dewey->get('roles');
// No more lewey
$data->remove('hosts.lewey');
// Add DB to hewey's roles
$data->append('hosts.hewey.roles', 'db');
$data->set('hosts.april', [
'username' => 'aman',
'password' => '@---S',
'roles' => ['web'],
]);
// Check if a key exists (true to this case)
$hasKey = $data->has('hosts.dewey.username');
```
`Data` may be used as an array, since it implements `ArrayAccess` interface:
```php
// Get
$data->get('name') === $data['name']; // true
$data['name'] = 'Dewey';
// is equivalent to
$data->set($name, 'Dewey');
isset($data['name']) === $data->has('name');
// Remove key
unset($data['name']);
```
`/` can also be used as a path delimiter:
```php
$data->set('a/b/c', 'd');
echo $data->get('a/b/c'); // "d"
$data->get('a/b/c') === $data->get('a.b.c'); // true
```
License
-------
This library is licensed under the MIT License - see the LICENSE file
for details.
Community
---------
If you have questions or want to help out, join us in the
[#dflydev](irc://irc.freenode.net/#dflydev) channel on irc.freenode.net.

View File

@ -0,0 +1,67 @@
{
"name": "dflydev/dot-access-data",
"type": "library",
"description": "Given a deep data structure, access data by dot notation.",
"homepage": "https://github.com/dflydev/dflydev-dot-access-data",
"keywords": ["dot", "access", "data", "notation"],
"license": "MIT",
"authors": [
{
"name": "Dragonfly Development Inc.",
"email": "info@dflydev.com",
"homepage": "http://dflydev.com"
},
{
"name": "Beau Simensen",
"email": "beau@dflydev.com",
"homepage": "http://beausimensen.com"
},
{
"name": "Carlos Frutos",
"email": "carlos@kiwing.it",
"homepage": "https://github.com/cfrutos"
},
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com"
}
],
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.42",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.3",
"scrutinizer/ocular": "1.6.0",
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^4.0.0"
},
"autoload": {
"psr-4": {
"Dflydev\\DotAccessData\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Dflydev\\DotAccessData\\": "tests/"
}
},
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"scripts": {
"phpcs": "phpcs",
"phpstan": "phpstan analyse",
"phpunit": "phpunit --no-coverage",
"psalm": "psalm",
"test": [
"@phpcs",
"@phpstan",
"@psalm",
"@phpunit"
]
}
}

View File

@ -0,0 +1,286 @@
<?php
declare(strict_types=1);
/*
* This file is a part of dflydev/dot-access-data.
*
* (c) Dragonfly Development Inc.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Dflydev\DotAccessData;
use ArrayAccess;
use Dflydev\DotAccessData\Exception\DataException;
use Dflydev\DotAccessData\Exception\InvalidPathException;
use Dflydev\DotAccessData\Exception\MissingPathException;
/**
* @implements ArrayAccess<string, mixed>
*/
class Data implements DataInterface, ArrayAccess
{
private const DELIMITERS = ['.', '/'];
/**
* Internal representation of data data
*
* @var array<string, mixed>
*/
protected $data;
/**
* Constructor
*
* @param array<string, mixed> $data
*/
public function __construct(array $data = [])
{
$this->data = $data;
}
/**
* {@inheritdoc}
*/
public function append(string $key, $value = null): void
{
$currentValue =& $this->data;
$keyPath = self::keyToPathArray($key);
$endKey = array_pop($keyPath);
foreach ($keyPath as $currentKey) {
if (! isset($currentValue[$currentKey])) {
$currentValue[$currentKey] = [];
}
$currentValue =& $currentValue[$currentKey];
}
if (!isset($currentValue[$endKey])) {
$currentValue[$endKey] = [];
}
if (!is_array($currentValue[$endKey])) {
// Promote this key to an array.
// TODO: Is this really what we want to do?
$currentValue[$endKey] = [$currentValue[$endKey]];
}
$currentValue[$endKey][] = $value;
}
/**
* {@inheritdoc}
*/
public function set(string $key, $value = null): void
{
$currentValue =& $this->data;
$keyPath = self::keyToPathArray($key);
$endKey = array_pop($keyPath);
foreach ($keyPath as $currentKey) {
if (!isset($currentValue[$currentKey])) {
$currentValue[$currentKey] = [];
}
if (!is_array($currentValue[$currentKey])) {
throw new DataException(sprintf('Key path "%s" within "%s" cannot be indexed into (is not an array)', $currentKey, self::formatPath($key)));
}
$currentValue =& $currentValue[$currentKey];
}
$currentValue[$endKey] = $value;
}
/**
* {@inheritdoc}
*/
public function remove(string $key): void
{
$currentValue =& $this->data;
$keyPath = self::keyToPathArray($key);
$endKey = array_pop($keyPath);
foreach ($keyPath as $currentKey) {
if (!isset($currentValue[$currentKey])) {
return;
}
$currentValue =& $currentValue[$currentKey];
}
unset($currentValue[$endKey]);
}
/**
* {@inheritdoc}
*
* @psalm-mutation-free
*/
public function get(string $key, $default = null)
{
/** @psalm-suppress ImpureFunctionCall */
$hasDefault = \func_num_args() > 1;
$currentValue = $this->data;
$keyPath = self::keyToPathArray($key);
foreach ($keyPath as $currentKey) {
if (!is_array($currentValue) || !array_key_exists($currentKey, $currentValue)) {
if ($hasDefault) {
return $default;
}
throw new MissingPathException($key, sprintf('No data exists at the given path: "%s"', self::formatPath($keyPath)));
}
$currentValue = $currentValue[$currentKey];
}
return $currentValue === null ? $default : $currentValue;
}
/**
* {@inheritdoc}
*
* @psalm-mutation-free
*/
public function has(string $key): bool
{
$currentValue = $this->data;
foreach (self::keyToPathArray($key) as $currentKey) {
if (
!is_array($currentValue) ||
!array_key_exists($currentKey, $currentValue)
) {
return false;
}
$currentValue = $currentValue[$currentKey];
}
return true;
}
/**
* {@inheritdoc}
*
* @psalm-mutation-free
*/
public function getData(string $key): DataInterface
{
$value = $this->get($key);
if (is_array($value) && Util::isAssoc($value)) {
return new Data($value);
}
throw new DataException(sprintf('Value at "%s" could not be represented as a DataInterface', self::formatPath($key)));
}
/**
* {@inheritdoc}
*/
public function import(array $data, int $mode = self::REPLACE): void
{
$this->data = Util::mergeAssocArray($this->data, $data, $mode);
}
/**
* {@inheritdoc}
*/
public function importData(DataInterface $data, int $mode = self::REPLACE): void
{
$this->import($data->export(), $mode);
}
/**
* {@inheritdoc}
*
* @psalm-mutation-free
*/
public function export(): array
{
return $this->data;
}
/**
* {@inheritdoc}
*
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists($key)
{
return $this->has($key);
}
/**
* {@inheritdoc}
*
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($key)
{
return $this->get($key, null);
}
/**
* {@inheritdoc}
*
* @param string $key
* @param mixed $value
*
* @return void
*/
#[\ReturnTypeWillChange]
public function offsetSet($key, $value)
{
$this->set($key, $value);
}
/**
* {@inheritdoc}
*
* @return void
*/
#[\ReturnTypeWillChange]
public function offsetUnset($key)
{
$this->remove($key);
}
/**
* @param string $path
*
* @return string[]
*
* @psalm-return non-empty-list<string>
*
* @psalm-pure
*/
protected static function keyToPathArray(string $path): array
{
if (\strlen($path) === 0) {
throw new InvalidPathException('Path cannot be an empty string');
}
$path = \str_replace(self::DELIMITERS, '.', $path);
return \explode('.', $path);
}
/**
* @param string|string[] $path
*
* @return string
*
* @psalm-pure
*/
protected static function formatPath($path): string
{
if (is_string($path)) {
$path = self::keyToPathArray($path);
}
return implode(' » ', $path);
}
}

View File

@ -0,0 +1,131 @@
<?php
declare(strict_types=1);
/*
* This file is a part of dflydev/dot-access-data.
*
* (c) Dragonfly Development Inc.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Dflydev\DotAccessData;
use Dflydev\DotAccessData\Exception\DataException;
use Dflydev\DotAccessData\Exception\InvalidPathException;
interface DataInterface
{
public const PRESERVE = 0;
public const REPLACE = 1;
public const MERGE = 2;
/**
* Append a value to a key (assumes key refers to an array value)
*
* If the key does not yet exist it will be created.
* If the key references a non-array it's existing contents will be added into a new array before appending the new value.
*
* @param string $key
* @param mixed $value
*
* @throws InvalidPathException if the given key is empty
*/
public function append(string $key, $value = null): void;
/**
* Set a value for a key
*
* If the key does not yet exist it will be created.
*
* @param string $key
* @param mixed $value
*
* @throws InvalidPathException if the given key is empty
* @throws DataException if the given key does not target an array
*/
public function set(string $key, $value = null): void;
/**
* Remove a key
*
* No exception will be thrown if the key does not exist
*
* @param string $key
*
* @throws InvalidPathException if the given key is empty
*/
public function remove(string $key): void;
/**
* Get the raw value for a key
*
* If the key does not exist, an optional default value can be returned instead.
* If no default is provided then an exception will be thrown instead.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*
* @throws InvalidPathException if the given key is empty
* @throws InvalidPathException if the given key does not exist and no default value was given
*
* @psalm-mutation-free
*/
public function get(string $key, $default = null);
/**
* Check if the key exists
*
* @param string $key
*
* @return bool
*
* @throws InvalidPathException if the given key is empty
*
* @psalm-mutation-free
*/
public function has(string $key): bool;
/**
* Get a data instance for a key
*
* @param string $key
*
* @return DataInterface
*
* @throws InvalidPathException if the given key is empty
* @throws DataException if the given key does not reference an array
*
* @psalm-mutation-free
*/
public function getData(string $key): DataInterface;
/**
* Import data into existing data
*
* @param array<string, mixed> $data
* @param self::PRESERVE|self::REPLACE|self::MERGE $mode
*/
public function import(array $data, int $mode = self::REPLACE): void;
/**
* Import data from an external data into existing data
*
* @param DataInterface $data
* @param self::PRESERVE|self::REPLACE|self::MERGE $mode
*/
public function importData(DataInterface $data, int $mode = self::REPLACE): void;
/**
* Export data as raw data
*
* @return array<string, mixed>
*
* @psalm-mutation-free
*/
public function export(): array;
}

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
/*
* This file is a part of dflydev/dot-access-data.
*
* (c) Dragonfly Development Inc.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Dflydev\DotAccessData\Exception;
/**
* Base runtime exception type thrown by this library
*/
class DataException extends \RuntimeException
{
}

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
/*
* This file is a part of dflydev/dot-access-data.
*
* (c) Dragonfly Development Inc.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Dflydev\DotAccessData\Exception;
/**
* Thrown when trying to access an invalid path in the data array
*/
class InvalidPathException extends DataException
{
}

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/*
* This file is a part of dflydev/dot-access-data.
*
* (c) Dragonfly Development Inc.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Dflydev\DotAccessData\Exception;
use Throwable;
/**
* Thrown when trying to access a path that does not exist
*/
class MissingPathException extends DataException
{
/** @var string */
protected $path;
public function __construct(string $path, string $message = '', int $code = 0, Throwable $previous = null)
{
$this->path = $path;
parent::__construct($message, $code, $previous);
}
public function getPath(): string
{
return $this->path;
}
}

View File

@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
/*
* This file is a part of dflydev/dot-access-data.
*
* (c) Dragonfly Development Inc.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Dflydev\DotAccessData;
class Util
{
/**
* Test if array is an associative array
*
* Note that this function will return true if an array is empty. Meaning
* empty arrays will be treated as if they are associative arrays.
*
* @param array<mixed> $arr
*
* @return bool
*
* @psalm-pure
*/
public static function isAssoc(array $arr): bool
{
return !count($arr) || count(array_filter(array_keys($arr), 'is_string')) == count($arr);
}
/**
* Merge contents from one associtative array to another
*
* @param mixed $to
* @param mixed $from
* @param DataInterface::PRESERVE|DataInterface::REPLACE|DataInterface::MERGE $mode
*
* @return mixed
*
* @psalm-pure
*/
public static function mergeAssocArray($to, $from, int $mode = DataInterface::REPLACE)
{
if ($mode === DataInterface::MERGE && self::isList($to) && self::isList($from)) {
return array_merge($to, $from);
}
if (is_array($from) && is_array($to)) {
foreach ($from as $k => $v) {
if (!isset($to[$k])) {
$to[$k] = $v;
} else {
$to[$k] = self::mergeAssocArray($to[$k], $v, $mode);
}
}
return $to;
}
return $mode === DataInterface::PRESERVE ? $to : $from;
}
/**
* @param mixed $value
*
* @return bool
*
* @psalm-pure
*/
private static function isList($value): bool
{
return is_array($value) && array_values($value) === $value;
}
}

View File

@ -0,0 +1,104 @@
<?php
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPSTORM_META
{
expectedArguments(\League\CommonMark\Util\HtmlElement::__construct(), 0, 'a', 'abbr', 'address', 'area', 'article', 'aside', 'audio', 'b', 'base', 'bdi', 'bdo', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'cite', 'code', 'col', 'colgroup', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kdb', 'keygen', 'label', 'legend', 'li', 'link', 'main', 'map', 'mark', 'menu', 'menuitem', 'meta', 'meter', 'nav', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'pre', 'progress', 'q', 's', 'samp', 'script', 'section', 'select', 'small', 'source', 'span', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'u', 'ul', 'var', 'video', 'wbr');
expectedArguments(\League\CommonMark\Extension\CommonMark\Node\Block\Heading::__construct(), 0, 1, 2, 3, 4, 5, 6);
expectedReturnValues(\League\CommonMark\Extension\CommonMark\Node\Block\Heading::getLevel(), 1, 2, 3, 4, 5, 6);
registerArgumentsSet('league_commonmark_htmlblock_types', \League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock::TYPE_1_CODE_CONTAINER, \League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock::TYPE_2_COMMENT, \League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock::TYPE_3, \League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock::TYPE_4, \League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock::TYPE_5_CDATA, \League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock::TYPE_6_BLOCK_ELEMENT, \League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock::TYPE_7_MISC_ELEMENT);
expectedArguments(\League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock::__construct(), 0, argumentsSet('league_commonmark_htmlblock_types'));
expectedArguments(\League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock::setType(), 0, argumentsSet('league_commonmark_htmlblock_types'));
expectedReturnValues(\League\CommonMark\Extension\CommonMark\Node\Block\HtmlBlock::getType(), argumentsSet('league_commonmark_htmlblock_types'));
expectedArguments(\League\CommonMark\Util\RegexHelper::getHtmlBlockOpenRegex(), 0, argumentsSet('league_commonmark_htmlblock_types'));
expectedArguments(\League\CommonMark\Util\RegexHelper::getHtmlBlockCloseRegex(), 0, argumentsSet('league_commonmark_htmlblock_types'));
registerArgumentsSet('league_commonmark_newline_types', \League\CommonMark\Node\Inline\Newline::HARDBREAK, \League\CommonMark\Node\Inline\Newline::SOFTBREAK);
expectedArguments(\League\CommonMark\Node\Inline\Newline::__construct(), 0, argumentsSet('league_commonmark_newline_types'));
expectedReturnValues(\League\CommonMark\Node\Inline\Newline::getType(), argumentsSet('league_commonmark_newline_types'));
registerArgumentsSet('league_commonmark_options',
'html_input',
'allow_unsafe_links',
'max_nesting_level',
'renderer',
'renderer/block_separator',
'renderer/inner_separator',
'renderer/soft_break',
'commonmark',
'commonmark/enable_em',
'commonmark/enable_strong',
'commonmark/use_asterisk',
'commonmark/use_underscore',
'commonmark/unordered_list_markers',
'disallowed_raw_html',
'disallowed_raw_html/disallowed_tags',
'external_link',
'external_link/html_class',
'external_link/internal_hosts',
'external_link/nofollow',
'external_link/noopener',
'external_link/noreferrer',
'external_link/open_in_new_window',
'footnote',
'footnote/backref_class',
'footnote/backref_symbol',
'footnote/container_add_hr',
'footnote/container_class',
'footnote/ref_class',
'footnote/ref_id_prefix',
'footnote/footnote_class',
'footnote/footnote_id_prefix',
'heading_permalink',
'heading_permalink/apply_id_to_heading',
'heading_permalink/heading_class',
'heading_permalink/html_class',
'heading_permalink/fragment_prefix',
'heading_permalink/id_prefix',
'heading_permalink/inner_contents',
'heading_permalink/insert',
'heading_permalink/max_heading_level',
'heading_permalink/min_heading_level',
'heading_permalink/symbol',
'heading_permalink/title',
'mentions',
'smartpunct/double_quote_closer',
'smartpunct/double_quote_opener',
'smartpunct/single_quote_closer',
'smartpunct/single_quote_opener',
'slug_normalizer',
'slug_normalizer/instance',
'slug_normalizer/max_length',
'slug_normalizer/unique',
'table',
'table/wrap',
'table/wrap/attributes',
'table/wrap/enabled',
'table/wrap/tag',
'table/alignment_attributes',
'table/alignment_attributes/left',
'table/alignment_attributes/center',
'table/alignment_attributes/right',
'table_of_contents',
'table_of_contents/html_class',
'table_of_contents/max_heading_level',
'table_of_contents/min_heading_level',
'table_of_contents/normalize',
'table_of_contents/placeholder',
'table_of_contents/position',
'table_of_contents/style',
);
expectedArguments(\League\Config\ConfigurationInterface::get(), 0, argumentsSet('league_commonmark_options'));
expectedArguments(\League\Config\ConfigurationInterface::exists(), 0, argumentsSet('league_commonmark_options'));
expectedArguments(\League\Config\MutableConfigurationInterface::set(), 0, argumentsSet('league_commonmark_options'));
}

588
vendor/league/commonmark/CHANGELOG.md vendored Normal file
View File

@ -0,0 +1,588 @@
# Change Log
All notable changes to this project will be documented in this file.
Updates should follow the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
**Upgrading from 1.x?** See <https://commonmark.thephpleague.com/2.0/upgrading/> for additional information.
## [Unreleased][unreleased]
## [2.4.0] - 2023-03-24
### Added
- Added generic `CommonMarkException` marker interface for all exceptions thrown by the library
- Added several new specific exception types implementing that marker interface:
- `AlreadyInitializedException`
- `InvalidArgumentException`
- `IOException`
- `LogicException`
- `MissingDependencyException`
- `NoMatchingRendererException`
- `ParserLogicException`
- Added more configuration options to the Heading Permalinks extension (#939):
- `heading_permalink/apply_id_to_heading` - When `true`, the `id` attribute will be applied to the heading element itself instead of the `<a>` tag
- `heading_permalink/heading_class` - class to apply to the heading element
- `heading_permalink/insert` - now accepts `none` to prevent the creation of the `<a>` link
- Added new `table/alignment_attributes` configuration option to control how table cell alignment is rendered (#959)
### Changed
- Change several thrown exceptions from `RuntimeException` to `LogicException` (or something extending it), including:
- `CallbackGenerator`s that fail to set a URL or return an expected value
- `MarkdownParser` when deactivating the last block parser or attempting to get an active block parser when they've all been closed
- Adding items to an already-initialized `Environment`
- Rendering a `Node` when no renderer has been registered for it
- `HeadingPermalinkProcessor` now throws `InvalidConfigurationException` instead of `RuntimeException` when invalid config values are given.
- `HtmlElement::setAttribute()` no longer requires the second parameter for boolean attributes
- Several small micro-optimizations
- Changed Strikethrough to only allow 1 or 2 tildes per the updated GFM spec
### Fixed
- Fixed inaccurate `@throws` docblocks throughout the codebase, including `ConverterInterface`, `MarkdownConverter`, and `MarkdownConverterInterface`.
- These previously suggested that only `\RuntimeException`s were thrown, which was inaccurate as `\LogicException`s were also possible.
## [2.3.9] - 2023-02-15
### Fixed
- Fixed autolink extension not detecting some URIs with underscores (#956)
## [2.3.8] - 2022-12-10
### Fixed
- Fixed parsing issues when `mb_internal_encoding()` is set to something other than `UTF-8` (#951)
## [2.3.7] - 2022-11-03
### Fixed
- Fixed `TaskListItemMarkerRenderer` not including HTML attributes set on the node by other extensions (#947)
## [2.3.6] - 2022-10-30
### Fixed
- Fixed unquoted attribute parsing when closing curly brace is followed by certain characters (like a `.`) (#943)
## [2.3.5] - 2022-07-29
### Fixed
- Fixed error using `InlineParserEngine` when no inline parsers are registered in the `Environment` (#908)
## [2.3.4] - 2022-07-17
### Changed
- Made a number of small tweaks to the embed extension's parsing behavior to fix #898:
- Changed `EmbedStartParser` to always capture embed-like lines in container blocks, regardless of parent block type
- Changed `EmbedProcessor` to also remove `Embed` blocks that aren't direct children of the `Document`
- Increased the priority of `EmbedProcessor` to `1010`
### Fixed
- Fixed `EmbedExtension` not parsing embeds following a list block (#898)
## [2.3.3] - 2022-06-07
### Fixed
- Fixed `DomainFilteringAdapter` not reindexing the embed list (#884, #885)
## [2.3.2] - 2022-06-03
### Fixed
- Fixed FootnoteExtension stripping extra characters from tab-indented footnotes (#881)
## [2.2.5] - 2022-06-03
### Fixed
- Fixed FootnoteExtension stripping extra characters from tab-indented footnotes (#881)
## [2.3.1] - 2022-05-14
### Fixed
- Fixed AutolinkExtension not ignoring trailing strikethrough syntax (#867)
## [2.2.4] - 2022-05-14
### Fixed
- Fixed AutolinkExtension not ignoring trailing strikethrough syntax (#867)
## [2.3.0] - 2022-04-07
### Added
- Added new `EmbedExtension` (#805)
- Added `DocumentRendererInterface` as a replacement for the now-deprecated `MarkdownRendererInterface`
### Deprecated
- Deprecated `MarkdownRendererInterface`; use `DocumentRendererInterface` instead
## [2.2.3] - 2022-02-26
### Fixed
- Fixed front matter parsing with Windows line endings (#821)
## [2.1.3] - 2022-02-26
### Fixed
- Fixed front matter parsing with Windows line endings (#821)
## [2.0.4] - 2022-02-26
### Fixed
- Fixed front matter parsing with Windows line endings (#821)
## [2.2.2] - 2022-02-13
### Fixed
- Fixed double-escaping of image alt text (#806, #810)
- Fixed Psalm typehints for event class names
## [2.2.1] - 2022-01-25
### Fixed
- Fixed `symfony/deprecation-contracts` constraint
### Removed
- Removed deprecation trigger from `MarkdownConverterInterface` to reduce noise
## [2.2.0] - 2022-01-22
### Added
- Added new `ConverterInterface`
- Added new `MarkdownToXmlConverter` class
- Added new `HtmlDecorator` class which can wrap existing renderers with additional HTML tags
- Added new `table/wrap` config to apply an optional wrapping/container element around a table (#780)
### Changed
- `HtmlElement` contents can now consist of any `Stringable`, not just `HtmlElement` and `string`
### Deprecated
- Deprecated `MarkdownConverterInterface` and its `convertToHtml()` method; use `ConverterInterface` and `convert()` instead
## [2.1.2] - 2022-02-13
### Fixed
- Fixed double-escaping of image alt text (#806, #810)
- Fixed Psalm typehints for event class names
## [2.1.1] - 2022-01-02
### Added
- Added missing return type to `Environment::dispatch()` to fix deprecation warning (#778)
## [2.1.0] - 2021-12-05
### Added
- Added support for ext-yaml in FrontMatterExtension (#715)
- Added support for symfony/yaml v6.0 in FrontMatterExtension (#739)
- Added new `heading_permalink/aria_hidden` config option (#741)
### Fixed
- Fixed PHP 8.1 deprecation warning (#759, #762)
## [2.0.3] - 2022-02-13
### Fixed
- Fixed double-escaping of image alt text (#806, #810)
- Fixed Psalm typehints for event class names
## [2.0.2] - 2021-08-14
### Changed
- Bumped minimum version of league/config to support PHP 8.1
### Fixed
- Fixed ability to register block parsers that identify lines starting with letters (#706)
## [2.0.1] - 2021-07-31
### Fixed
- Fixed nested autolinks (#689)
- Fixed description lists being parsed incorrectly (#692)
- Fixed Table of Contents not respecting Heading Permalink prefixes (#690)
## [2.0.0] - 2021-07-24
No changes were introduced since the previous RC2 release.
See all entries below for a list of changes between 1.x and 2.0.
## [2.0.0-rc2] - 2021-07-17
### Fixed
- Fixed Mentions inside of links creating nested links against the spec's rules (#688)
## [2.0.0-rc1] - 2021-07-10
No changes were introduced since the previous release.
## [2.0.0-beta3] - 2021-07-03
### Changed
- Any leading UTF-8 BOM will be stripped from the input
- The `getEnvironment()` method of `CommonMarkConverter` and `GithubFlavoredMarkdownConverter` will always return the concrete, configurable `Environment` for upgrading convenience
- Optimized AST iteration
- Lots of small micro-optimizations
## [2.0.0-beta2] - 2021-06-27
### Added
- Added new `Node::iterator()` method and `NodeIterator` class for faster AST iteration (#683, #684)
### Changed
- Made compatible with CommonMark spec 0.30.0
- Optimized link label parsing
- Optimized AST iteration for a 50% performance boost in some event listeners (#683, #684)
### Fixed
- Fixed processing instructions with EOLs
- Fixed case-insensitive matching for HTML tag types
- Fixed type 7 HTML blocks incorrectly interrupting lazy paragraphs
- Fixed newlines in reference labels not collapsing into spaces
- Fixed link label normalization with escaped newlines
- Fixed unnecessary AST iteration when no default attributes are configured
## [2.0.0-beta1] - 2021-06-20
### Added
- **Added three new extensions:**
- `FrontMatterExtension` ([see documentation](https://commonmark.thephpleague.com/extensions/front-matter/))
- `DescriptionListExtension` ([see documentation](https://commonmark.thephpleague.com/extensions/description-lists/))
- `DefaultAttributesExtension` ([see documentation](https://commonmark.thephpleague.com/extensions/default-attributes/))
- **Added new `XmlRenderer` to simplify AST debugging** ([see documentation](https://commonmark.thephpleague.com/xml/)) (#431)
- **Added the ability to configure disallowed raw HTML tags** (#507)
- **Added the ability for Mentions to use multiple characters for their symbol** (#514, #550)
- **Added the ability to delegate event dispatching to PSR-14 compliant event dispatcher libraries**
- **Added new configuration options:**
- Added `heading_permalink/min_heading_level` and `heading_permalink/max_heading_level` options to control which headings get permalinks (#519)
- Added `heading_permalink/fragment_prefix` to allow customizing the URL fragment prefix (#602)
- Added `footnote/backref_symbol` option for customizing backreference link appearance (#522)
- Added `slug_normalizer/max_length` option to control the maximum length of generated URL slugs
- Added `slug_normalizer/unique` option to control whether unique slugs should be generated per-document or per-environment
- **Added purity markers throughout the codebase** (verified with Psalm)
- Added `Query` class to simplify Node traversal when looking to take action on certain Nodes
- Added new `HtmlFilter` and `StringContainerHelper` utility classes
- Added new `AbstractBlockContinueParser` class to simplify the creation of custom block parsers
- Added several new classes and interfaces:
- `BlockContinue`
- `BlockContinueParserInterface`
- `BlockContinueParserWithInlinesInterface`
- `BlockStart`
- `BlockStartParserInterface`
- `ChildNodeRendererInterface`
- `ConfigurableExtensionInterface`
- `CursorState`
- `DashParser` (extracted from `PunctuationParser`)
- `DelimiterParser`
- `DocumentBlockParser`
- `DocumentPreRenderEvent`
- `DocumentRenderedEvent`
- `EllipsesParser` (extracted from `PunctuationParser`)
- `ExpressionInterface`
- `FallbackNodeXmlRenderer`
- `InlineParserEngineInterface`
- `InlineParserMatch`
- `MarkdownParserState`
- `MarkdownParserStateInterface`
- `MarkdownRendererInterface`
- `Query`
- `RawMarkupContainerInterface`
- `ReferenceableInterface`
- `RenderedContent`
- `RenderedContentInterface`
- `ReplaceUnpairedQuotesListener`
- `SpecReader`
- `TableOfContentsRenderer`
- `UniqueSlugNormalizer`
- `UniqueSlugNormalizerInterface`
- `XmlRenderer`
- `XmlNodeRendererInterface`
- Added several new methods:
- `Cursor::getCurrentCharacter()`
- `Environment::createDefaultConfiguration()`
- `Environment::setEventDispatcher()`
- `EnvironmentInterface::getExtensions()`
- `EnvironmentInterface::getInlineParsers()`
- `EnvironmentInterface::getSlugNormalizer()`
- `FencedCode::setInfo()`
- `Heading::setLevel()`
- `HtmlRenderer::renderDocument()`
- `InlineParserContext::getFullMatch()`
- `InlineParserContext::getFullMatchLength()`
- `InlineParserContext::getMatches()`
- `InlineParserContext::getSubMatches()`
- `LinkParserHelper::parsePartialLinkLabel()`
- `LinkParserHelper::parsePartialLinkTitle()`
- `Node::assertInstanceOf()`
- `RegexHelper::isLetter()`
- `StringContainerInterface::setLiteral()`
- `TableCell::getType()`
- `TableCell::setType()`
- `TableCell::getAlign()`
- `TableCell::setAlign()`
### Changed
- **Changed the converter return type**
- `CommonMarkConverter::convertToHtml()` now returns an instance of `RenderedContentInterface`. This can be cast to a string for backward compatibility with 1.x.
- **Table of Contents items are no longer wrapped with `<p>` tags** (#613)
- **Heading Permalinks now link to element IDs instead of using `name` attributes** (#602)
- **Heading Permalink IDs and URL fragments now have a `content` prefix by default** (#602)
- **Changes to configuration options:**
- `enable_em` has been renamed to `commonmark/enable_em`
- `enable_strong` has been renamed to `commonmark/enable_strong`
- `use_asterisk` has been renamed to `commonmark/use_asterisk`
- `use_underscore` has been renamed to `commonmark/use_underscore`
- `unordered_list_markers` has been renamed to `commonmark/unordered_list_markers`
- `mentions/*/symbol` has been renamed to `mentions/*/prefix`
- `mentions/*/regex` has been renamed to `mentions/*/pattern` and requires partial regular expressions (without delimiters or flags)
- `max_nesting_level` now defaults to `PHP_INT_MAX` and no longer supports floats
- `heading_permalink/slug_normalizer` has been renamed to `slug_normalizer/instance`
- **Event dispatching is now fully PSR-14 compliant**
- **Moved and renamed several classes** - [see the full list here](https://commonmark.thephpleague.com/2.0/upgrading/#classesnamespaces-renamed)
- The `HeadingPermalinkExtension` and `FootnoteExtension` were modified to ensure they never produce a slug which conflicts with slugs created by the other extension
- `SlugNormalizer::normalizer()` now supports optional prefixes and max length options passed in via the `$context` argument
- The `AbstractBlock::$data` and `AbstractInline::$data` arrays were replaced with a `Data` array-like object on the base `Node` class
- **Implemented a new approach to block parsing.** This was a massive change, so here are the highlights:
- Functionality previously found in block parsers and node elements has moved to block parser factories and block parsers, respectively ([more details](https://commonmark.thephpleague.com/2.0/upgrading/#new-block-parsing-approach))
- `ConfigurableEnvironmentInterface::addBlockParser()` is now `EnvironmentBuilderInterface::addBlockParserFactory()`
- `ReferenceParser` was re-implemented and works completely different than before
- The paragraph parser no longer needs to be added manually to the environment
- **Implemented a new approach to inline parsing** where parsers can now specify longer strings or regular expressions they want to parse (instead of just single characters):
- `InlineParserInterface::getCharacters()` is now `getMatchDefinition()` and returns an instance of `InlineParserMatch`
- `InlineParserContext::__construct()` now requires the contents to be provided as a `Cursor` instead of a `string`
- **Implemented delimiter parsing as a special type of inline parser** (via the new `DelimiterParser` class)
- **Changed block and inline rendering to use common methods and interfaces**
- `BlockRendererInterface` and `InlineRendererInterface` were replaced by `NodeRendererInterface` with slightly different parameters. All core renderers now implement this interface.
- `ConfigurableEnvironmentInterface::addBlockRenderer()` and `addInlineRenderer()` were combined into `EnvironmentBuilderInterface::addRenderer()`
- `EnvironmentInterface::getBlockRenderersForClass()` and `getInlineRenderersForClass()` are now just `getRenderersForClass()`
- **Completely refactored the Configuration implementation**
- All configuration-specific classes have been moved into a new `league/config` package with a new namespace
- `Configuration` objects must now be configured with a schema and all options must match that schema - arbitrary keys are no longer permitted
- `Configuration::__construct()` no longer accepts the default configuration values - use `Configuration::merge()` instead
- `ConfigurationInterface` now only contains a `get(string $key)`; this method no longer allows arbitrary default values to be returned if the option is missing
- `ConfigurableEnvironmentInterface` was renamed to `EnvironmentBuilderInterface`
- `ExtensionInterface::register()` now requires an `EnvironmentBuilderInterface` param instead of `ConfigurableEnvironmentInterface`
- **Added missing return types to virtually every class and interface method**
- Re-implemented the GFM Autolink extension using the new inline parser approach instead of document processors
- `EmailAutolinkProcessor` is now `EmailAutolinkParser`
- `UrlAutolinkProcessor` is now `UrlAutolinkParser`
- `HtmlElement` can now properly handle array (i.e. `class`) and boolean (i.e. `checked`) attribute values
- `HtmlElement` automatically flattens any attributes with array values into space-separated strings, removing duplicate entries
- Combined separate classes/interfaces into one:
- `DisallowedRawHtmlRenderer` replaces `DisallowedRawHtmlBlockRenderer` and `DisallowedRawHtmlInlineRenderer`
- `NodeRendererInterface` replaces `BlockRendererInterface` and `InlineRendererInterface`
- Renamed the following methods:
- `Environment` and `ConfigurableEnvironmentInterface`:
- `addBlockParser()` is now `addBlockStartParser()`
- `ReferenceMap` and `ReferenceMapInterface`:
- `addReference()` is now `add()`
- `getReference()` is now `get()`
- `listReferences()` is now `getIterator()`
- Various node (block/inline) classes:
- `getContent()` is now `getLiteral()`
- `setContent()` is now `setLiteral()`
- Moved and renamed the following constants:
- `EnvironmentInterface::HTML_INPUT_ALLOW` is now `HtmlFilter::ALLOW`
- `EnvironmentInterface::HTML_INPUT_ESCAPE` is now `HtmlFilter::ESCAPE`
- `EnvironmentInterface::HTML_INPUT_STRIP` is now `HtmlFilter::STRIP`
- `TableCell::TYPE_HEAD` is now `TableCell::TYPE_HEADER`
- `TableCell::TYPE_BODY` is now `TableCell::TYPE_DATA`
- Changed the visibility of the following properties:
- `AttributesInline::$attributes` is now `private`
- `AttributesInline::$block` is now `private`
- `TableCell::$align` is now `private`
- `TableCell::$type` is now `private`
- `TableSection::$type` is now `private`
- Several methods which previously returned `$this` now return `void`
- `Delimiter::setPrevious()`
- `Node::replaceChildren()`
- `Context::setTip()`
- `Context::setContainer()`
- `Context::setBlocksParsed()`
- `AbstractStringContainer::setContent()`
- `AbstractWebResource::setUrl()`
- Several classes are now marked `final`:
- `ArrayCollection`
- `Emphasis`
- `FencedCode`
- `Heading`
- `HtmlBlock`
- `HtmlElement`
- `HtmlInline`
- `IndentedCode`
- `Newline`
- `Strikethrough`
- `Strong`
- `Text`
- `Heading` nodes no longer directly contain a copy of their inner text
- `StringContainerInterface` can now be used for inlines, not just blocks
- `ArrayCollection` only supports integer keys
- `HtmlElement` now implements `Stringable`
- `Cursor::saveState()` and `Cursor::restoreState()` now use `CursorState` objects instead of arrays
- `NodeWalker::next()` now enters, traverses any children, and leaves all elements which may have children (basically all blocks plus any inlines with children). Previously, it only did this for elements explicitly marked as "containers".
- `InvalidOptionException` was removed
- Anything with a `getReference(): ReferenceInterface` method now implements `ReferencableInterface`
- The `SmartPunct` extension now replaces all unpaired `Quote` elements with `Text` elements towards the end of parsing, making the `QuoteRenderer` unnecessary
- Several changes made to the Footnote extension:
- Footnote identifiers can no longer contain spaces
- Anonymous footnotes can now span subsequent lines
- Footnotes can now contain multiple lines of content, including sub-blocks, by indenting them
- Footnote event listeners now have numbered priorities (but still execute in the same order)
- Footnotes must now be separated from previous content by a blank line
- The line numbers (keys) returned via `MarkdownInput::getLines()` now start at 1 instead of 0
- `DelimiterProcessorCollectionInterface` now extends `Countable`
- `RegexHelper::PARTIAL_` constants must always be used in case-insensitive contexts
- `HeadingPermalinkProcessor` no longer accepts text normalizers via the constructor - these must be provided via configuration instead
- Blocks which can't contain inlines will no longer be asked to render inlines
- `AnonymousFootnoteRefParser` and `HeadingPermalinkProcessor` now implement `EnvironmentAwareInterface` instead of `ConfigurationAwareInterface`
- The second argument to `TextNormalizerInterface::normalize()` must now be an array
- The `title` attribute for `Link` and `Image` nodes is now stored using a dedicated property instead of stashing it in `$data`
- `ListData::$delimiter` now returns either `ListBlock::DELIM_PERIOD` or `ListBlock::DELIM_PAREN` instead of the literal delimiter
### Fixed
- **Fixed parsing of footnotes without content**
- **Fixed rendering of orphaned footnotes and footnote refs**
- **Fixed some URL autolinks breaking too early** (#492)
- Fixed `AbstractStringContainer` not actually being `abstract`
### Removed
- **Removed support for PHP 7.1, 7.2, and 7.3** (#625, #671)
- **Removed all previously-deprecated functionality:**
- Removed the ability to pass custom `Environment` instances into the `CommonMarkConverter` and `GithubFlavoredMarkdownConverter` constructors
- Removed the `Converter` class and `ConverterInterface`
- Removed the `bin/commonmark` script
- Removed the `Html5Entities` utility class
- Removed the `InlineMentionParser` (use `MentionParser` instead)
- Removed `DefaultSlugGenerator` and `SlugGeneratorInterface` from the `Extension/HeadingPermalink/Slug` sub-namespace (use the new ones under `./SlugGenerator` instead)
- Removed the following `ArrayCollection` methods:
- `add()`
- `set()`
- `get()`
- `remove()`
- `isEmpty()`
- `contains()`
- `indexOf()`
- `containsKey()`
- `replaceWith()`
- `removeGaps()`
- Removed the `ConfigurableEnvironmentInterface::setConfig()` method
- Removed the `ListBlock::TYPE_UNORDERED` constant
- Removed the `CommonMarkConverter::VERSION` constant
- Removed the `HeadingPermalinkRenderer::DEFAULT_INNER_CONTENTS` constant
- Removed the `heading_permalink/inner_contents` configuration option
- **Removed now-unused classes:**
- `AbstractStringContainerBlock`
- `BlockRendererInterface`
- `Context`
- `ContextInterface`
- `Converter`
- `ConverterInterface`
- `InlineRendererInterface`
- `PunctuationParser` (was split into two classes: `DashParser` and `EllipsesParser`)
- `QuoteRenderer`
- `UnmatchedBlockCloser`
- Removed the following methods, properties, and constants:
- `AbstractBlock::$open`
- `AbstractBlock::$lastLineBlank`
- `AbstractBlock::isContainer()`
- `AbstractBlock::canContain()`
- `AbstractBlock::isCode()`
- `AbstractBlock::matchesNextLine()`
- `AbstractBlock::endsWithBlankLine()`
- `AbstractBlock::setLastLineBlank()`
- `AbstractBlock::shouldLastLineBeBlank()`
- `AbstractBlock::isOpen()`
- `AbstractBlock::finalize()`
- `AbstractBlock::getData()`
- `AbstractInline::getData()`
- `ConfigurableEnvironmentInterface::addBlockParser()`
- `ConfigurableEnvironmentInterface::mergeConfig()`
- `Delimiter::setCanClose()`
- `EnvironmentInterface::getConfig()`
- `EnvironmentInterface::getInlineParsersForCharacter()`
- `EnvironmentInterface::getInlineParserCharacterRegex()`
- `HtmlRenderer::renderBlock()`
- `HtmlRenderer::renderBlocks()`
- `HtmlRenderer::renderInline()`
- `HtmlRenderer::renderInlines()`
- `Node::isContainer()`
- `RegexHelper::matchAll()` (use the new `matchFirst()` method instead)
- `RegexHelper::REGEX_WHITESPACE`
- Removed the second `$contents` argument from the `Heading` constructor
### Deprecated
**The following things have been deprecated and will not be supported in v3.0:**
- `Environment::mergeConfig()` (set configuration before instantiation instead)
- `Environment::createCommonMarkEnvironment()` and `Environment::createGFMEnvironment()`
- Alternative 1: Use `CommonMarkConverter` or `GithubFlavoredMarkdownConverter` if you don't need to customize the environment
- Alternative 2: Instantiate a new `Environment` and add the necessary extensions yourself
[unreleased]: https://github.com/thephpleague/commonmark/compare/2.4.0...main
[2.4.0]: https://github.com/thephpleague/commonmark/compare/2.3.9...2.4.0
[2.3.9]: https://github.com/thephpleague/commonmark/compare/2.3.8...2.3.9
[2.3.8]: https://github.com/thephpleague/commonmark/compare/2.3.7...2.3.8
[2.3.7]: https://github.com/thephpleague/commonmark/compare/2.3.6...2.3.7
[2.3.6]: https://github.com/thephpleague/commonmark/compare/2.3.5...2.3.6
[2.3.5]: https://github.com/thephpleague/commonmark/compare/2.3.4...2.3.5
[2.3.4]: https://github.com/thephpleague/commonmark/compare/2.3.3...2.3.4
[2.3.3]: https://github.com/thephpleague/commonmark/compare/2.3.2...2.3.3
[2.3.2]: https://github.com/thephpleague/commonmark/compare/2.3.2...main
[2.3.1]: https://github.com/thephpleague/commonmark/compare/2.3.0...2.3.1
[2.3.0]: https://github.com/thephpleague/commonmark/compare/2.2.3...2.3.0
[2.2.5]: https://github.com/thephpleague/commonmark/compare/2.2.4...2.2.5
[2.2.4]: https://github.com/thephpleague/commonmark/compare/2.2.3...2.2.4
[2.2.3]: https://github.com/thephpleague/commonmark/compare/2.2.2...2.2.3
[2.2.2]: https://github.com/thephpleague/commonmark/compare/2.2.1...2.2.2
[2.2.1]: https://github.com/thephpleague/commonmark/compare/2.2.0...2.2.1
[2.2.0]: https://github.com/thephpleague/commonmark/compare/2.1.1...2.2.0
[2.1.3]: https://github.com/thephpleague/commonmark/compare/2.1.2...2.1.3
[2.1.2]: https://github.com/thephpleague/commonmark/compare/2.1.1...2.1.2
[2.1.1]: https://github.com/thephpleague/commonmark/compare/2.0.2...2.1.1
[2.1.0]: https://github.com/thephpleague/commonmark/compare/2.0.2...2.1.0
[2.0.4]: https://github.com/thephpleague/commonmark/compare/2.0.3...2.0.4
[2.0.3]: https://github.com/thephpleague/commonmark/compare/2.0.2...2.0.3
[2.0.2]: https://github.com/thephpleague/commonmark/compare/2.0.1...2.0.2
[2.0.1]: https://github.com/thephpleague/commonmark/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/thephpleague/commonmark/compare/2.0.0-rc2...2.0.0
[2.0.0-rc2]: https://github.com/thephpleague/commonmark/compare/2.0.0-rc1...2.0.0-rc2
[2.0.0-rc1]: https://github.com/thephpleague/commonmark/compare/2.0.0-beta3...2.0.0-rc1
[2.0.0-beta3]: https://github.com/thephpleague/commonmark/compare/2.0.0-beta2...2.0.0-beta3
[2.0.0-beta2]: https://github.com/thephpleague/commonmark/compare/2.0.0-beta1...2.0.0-beta2
[2.0.0-beta1]: https://github.com/thephpleague/commonmark/compare/1.6...2.0.0-beta1

28
vendor/league/commonmark/LICENSE vendored Normal file
View File

@ -0,0 +1,28 @@
BSD 3-Clause License
Copyright (c) 2014-2022, Colin O'Dell. All rights reserved. Some code based on commonmark.js (copyright 2014-2018, John MacFarlane) and commonmark-java (copyright 2015-2016, Atlassian Pty Ltd)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

221
vendor/league/commonmark/README.md vendored Normal file
View File

@ -0,0 +1,221 @@
# league/commonmark
[![Latest Version](https://img.shields.io/packagist/v/league/commonmark.svg?style=flat-square)](https://packagist.org/packages/league/commonmark)
[![Total Downloads](https://img.shields.io/packagist/dt/league/commonmark.svg?style=flat-square)](https://packagist.org/packages/league/commonmark)
[![Software License](https://img.shields.io/badge/License-BSD--3-brightgreen.svg?style=flat-square)](LICENSE)
[![Build Status](https://img.shields.io/github/workflow/status/thephpleague/commonmark/Tests/main.svg?style=flat-square)](https://github.com/thephpleague/commonmark/actions?query=workflow%3ATests+branch%3Amain)
[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/thephpleague/commonmark.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/commonmark/code-structure)
[![Quality Score](https://img.shields.io/scrutinizer/g/thephpleague/commonmark.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/commonmark)
[![Psalm Type Coverage](https://shepherd.dev/github/thephpleague/commonmark/coverage.svg)](https://shepherd.dev/github/thephpleague/commonmark)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/126/badge)](https://bestpractices.coreinfrastructure.org/projects/126)
[![Sponsor development of this project](https://img.shields.io/badge/sponsor%20this%20package-%E2%9D%A4-ff69b4.svg?style=flat-square)](https://www.colinodell.com/sponsor)
![league/commonmark](commonmark-banner.png)
**league/commonmark** is a highly-extensible PHP Markdown parser created by [Colin O'Dell][@colinodell] which supports the full [CommonMark] spec and [GitHub-Flavored Markdown]. It is based on the [CommonMark JS reference implementation][commonmark.js] by [John MacFarlane] \([@jgm]\).
## 📦 Installation & Basic Usage
This project requires PHP 7.4 or higher with the `mbstring` extension. To install it via [Composer] simply run:
``` bash
$ composer require league/commonmark
```
The `CommonMarkConverter` class provides a simple wrapper for converting CommonMark to HTML:
```php
use League\CommonMark\CommonMarkConverter;
$converter = new CommonMarkConverter([
'html_input' => 'strip',
'allow_unsafe_links' => false,
]);
echo $converter->convert('# Hello World!');
// <h1>Hello World!</h1>
```
Or if you want GitHub-Flavored Markdown, use the `GithubFlavoredMarkdownConverter` class instead:
```php
use League\CommonMark\GithubFlavoredMarkdownConverter;
$converter = new GithubFlavoredMarkdownConverter([
'html_input' => 'strip',
'allow_unsafe_links' => false,
]);
echo $converter->convert('# Hello World!');
// <h1>Hello World!</h1>
```
Please note that only UTF-8 and ASCII encodings are supported. If your Markdown uses a different encoding please convert it to UTF-8 before running it through this library.
🔒 If you will be parsing untrusted input from users, please consider setting the `html_input` and `allow_unsafe_links` options per the example above. See <https://commonmark.thephpleague.com/security/> for more details. If you also do choose to allow raw HTML input from untrusted users, consider using a library (like [HTML Purifier](https://github.com/ezyang/htmlpurifier)) to provide additional HTML filtering.
## 📓 Documentation
Full documentation on advanced usage, configuration, and customization can be found at [commonmark.thephpleague.com][docs].
## ⏫ Upgrading
Information on how to upgrade to newer versions of this library can be found at <https://commonmark.thephpleague.com/releases>.
## 💻 GitHub-Flavored Markdown
The `GithubFlavoredMarkdownConverter` shown earlier is a drop-in replacement for the `CommonMarkConverter` which adds additional features found in the GFM spec:
- Autolinks
- Disallowed raw HTML
- Strikethrough
- Tables
- Task Lists
See the [Extensions documentation](https://commonmark.thephpleague.com/customization/extensions/) for more details on how to include only certain GFM features if you don't want them all.
## 🗃️ Related Packages
### Integrations
- [CakePHP 3](https://github.com/gourmet/common-mark)
- [Drupal](https://www.drupal.org/project/markdown)
- [Laravel 4+](https://github.com/GrahamCampbell/Laravel-Markdown)
- [Sculpin](https://github.com/bcremer/sculpin-commonmark-bundle)
- [Symfony 2 & 3](https://github.com/webuni/commonmark-bundle)
- [Symfony 4](https://github.com/avensome/commonmark-bundle)
- [Twig Markdown extension](https://github.com/twigphp/markdown-extension)
- [Twig filter and tag](https://github.com/aptoma/twig-markdown)
- [Laravel CommonMark Blog](https://github.com/spekulatius/laravel-commonmark-blog)
### Included Extensions
See [our extension documentation](https://commonmark.thephpleague.com/extensions/overview) for a full list of extensions bundled with this library.
### Community Extensions
Custom parsers/renderers can be bundled into extensions which extend CommonMark. Here are some that you may find interesting:
- [Alt Three Emoji](https://github.com/AltThree/Emoji) An emoji parser for CommonMark.
- [Sup Sub extensions](https://github.com/OWS/commonmark-sup-sub-extensions) - Adds support of superscript and subscript (`<sup>` and `<sub>` HTML tags)
- [YouTube iframe extension](https://github.com/zoonru/commonmark-ext-youtube-iframe) - Replaces youtube link with iframe.
- [Lazy Image extension](https://github.com/simonvomeyser/commonmark-ext-lazy-image) - Adds various options for lazy loading of images.
- [Marker Extension](https://github.com/noah1400/commonmark-marker-extension) - Adds support of highlighted text (`<mark>` HTML tag)
Others can be found on [Packagist under the `commonmark-extension` package type](https://packagist.org/packages/league/commonmark?type=commonmark-extension).
If you build your own, feel free to submit a PR to add it to this list!
### Others
Check out the other cool things people are doing with `league/commonmark`: <https://packagist.org/packages/league/commonmark/dependents>
## 🏷️ Versioning
[SemVer](http://semver.org/) is followed closely. Minor and patch releases should not introduce breaking changes to the codebase; however, they might change the resulting AST or HTML output of parsed Markdown (due to bug fixes, spec changes, etc.) As a result, you might get slightly different HTML, but any custom code built onto this library should still function correctly.
Any classes or methods marked `@internal` are not intended for use outside of this library and are subject to breaking changes at any time, so please avoid using them.
## 🛠️ Maintenance & Support
When a new **minor** version (e.g. `2.0` -> `2.1`) is released, the previous one (`2.0`) will continue to receive security and critical bug fixes for *at least* 3 months.
When a new **major** version is released (e.g. `1.6` -> `2.0`), the previous one (`1.6`) will receive critical bug fixes for *at least* 3 months and security updates for 6 months after that new release comes out.
(This policy may change in the future and exceptions may be made on a case-by-case basis.)
**Professional support, including notification of new releases and security updates, is available through a [Tidelift Subscription](https://tidelift.com/subscription/pkg/packagist-league-commonmark?utm_source=packagist-league-commonmark&utm_medium=referral&utm_campaign=readme).**
## 👷‍♀️ Contributing
To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure with us.
If you encounter a bug in the spec, please report it to the [CommonMark] project. Any resulting fix will eventually be implemented in this project as well.
Contributions to this library are **welcome**, especially ones that:
* Improve usability or flexibility without compromising our ability to adhere to the [CommonMark spec]
* Mirror fixes made to the [reference implementation][commonmark.js]
* Optimize performance
* Fix issues with adhering to the [CommonMark spec]
Major refactoring to core parsing logic should be avoided if possible so that we can easily follow updates made to [the reference implementation][commonmark.js]. That being said, we will absolutely consider changes which don't deviate too far from the reference spec or which are favored by other popular CommonMark implementations.
Please see [CONTRIBUTING](https://github.com/thephpleague/commonmark/blob/main/.github/CONTRIBUTING.md) for additional details.
## 🧪 Testing
``` bash
$ composer test
```
This will also test league/commonmark against the latest supported spec.
## 🚀 Performance Benchmarks
You can compare the performance of **league/commonmark** to other popular parsers by running the included benchmark tool:
``` bash
$ ./tests/benchmark/benchmark.php
```
## 👥 Credits & Acknowledgements
- [Colin O'Dell][@colinodell]
- [John MacFarlane][@jgm]
- [All Contributors]
This code is partially based on the [CommonMark JS reference implementation][commonmark.js] which is written, maintained and copyrighted by [John MacFarlane]. This project simply wouldn't exist without his work.
### Sponsors
We'd also like to extend our sincere thanks the following sponsors who support ongoing development of this project:
- [Tidelift](https://tidelift.com/subscription/pkg/packagist-league-commonmark?utm_source=packagist-league-commonmark&utm_medium=referral&utm_campaign=readme) for offering support to both the maintainers and end-users through their [professional support](https://tidelift.com/subscription/pkg/packagist-league-commonmark?utm_source=packagist-league-commonmark&utm_medium=referral&utm_campaign=readme) program
- [Blackfire](https://www.blackfire.io/) for providing an Open-Source Profiler subscription
- [JetBrains](https://www.jetbrains.com/) for supporting this project with complimentary [PhpStorm](https://www.jetbrains.com/phpstorm/) licenses
- [Taylor Otwell](https://twitter.com/taylorotwell) for sponsoring this project through GitHub sponsors
Are you interested in sponsoring development of this project? See <https://www.colinodell.com/sponsor> for a list of ways to contribute.
## 📄 License
**league/commonmark** is licensed under the BSD-3 license. See the [`LICENSE`](LICENSE) file for more details.
## 🏛️ Governance
This project is primarily maintained by [Colin O'Dell][@colinodell]. Members of the [PHP League] Leadership Team may occasionally assist with some of these duties.
## 🗺️ Who Uses It?
This project is used by [Drupal](https://www.drupal.org/project/markdown), [Laravel Framework](https://laravel.com/), [Cachet](https://cachethq.io/), [Firefly III](https://firefly-iii.org/), [Neos](https://www.neos.io/), [Daux.io](https://daux.io/), and [more](https://packagist.org/packages/league/commonmark/dependents)!
---
<div align="center">
<b>
<a href="https://tidelift.com/subscription/pkg/packagist-league-commonmark?utm_source=packagist-league-commonmark&utm_medium=referral&utm_campaign=readme">Get professional support for league/commonmark with a Tidelift subscription</a>
</b>
<br>
<sub>
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
</sub>
</div>
[CommonMark]: http://commonmark.org/
[CommonMark spec]: http://spec.commonmark.org/
[commonmark.js]: https://github.com/jgm/commonmark.js
[GitHub-Flavored Markdown]: https://github.github.com/gfm/
[John MacFarlane]: http://johnmacfarlane.net
[docs]: https://commonmark.thephpleague.com/
[docs-examples]: https://commonmark.thephpleague.com/customization/overview/#examples
[docs-example-twitter]: https://commonmark.thephpleague.com/customization/inline-parsing#example-1---twitter-handles
[docs-example-smilies]: https://commonmark.thephpleague.com/customization/inline-parsing#example-2---emoticons
[All Contributors]: https://github.com/thephpleague/commonmark/contributors
[@colinodell]: https://www.twitter.com/colinodell
[@jgm]: https://github.com/jgm
[jgm/stmd]: https://github.com/jgm/stmd
[Composer]: https://getcomposer.org/
[PHP League]: https://thephpleague.com

125
vendor/league/commonmark/composer.json vendored Normal file
View File

@ -0,0 +1,125 @@
{
"name": "league/commonmark",
"type": "library",
"description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)",
"keywords": ["markdown","parser","commonmark","gfm","github","flavored","github-flavored","md"],
"homepage": "https://commonmark.thephpleague.com",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com",
"role": "Lead Developer"
}
],
"support": {
"docs": "https://commonmark.thephpleague.com/",
"forum": "https://github.com/thephpleague/commonmark/discussions",
"issues": "https://github.com/thephpleague/commonmark/issues",
"rss": "https://github.com/thephpleague/commonmark/releases.atom",
"source": "https://github.com/thephpleague/commonmark"
},
"require": {
"php": "^7.4 || ^8.0",
"ext-mbstring": "*",
"league/config": "^1.1.1",
"psr/event-dispatcher": "^1.0",
"symfony/deprecation-contracts": "^2.1 || ^3.0",
"symfony/polyfill-php80": "^1.16"
},
"require-dev": {
"ext-json": "*",
"cebe/markdown": "^1.0",
"commonmark/cmark": "0.30.0",
"commonmark/commonmark.js": "0.30.0",
"composer/package-versions-deprecated": "^1.8",
"embed/embed": "^4.4",
"erusev/parsedown": "^1.0",
"github/gfm": "0.29.0",
"michelf/php-markdown": "^1.4 || ^2.0",
"nyholm/psr7": "^1.5",
"phpstan/phpstan": "^1.8.2",
"phpunit/phpunit": "^9.5.21",
"scrutinizer/ocular": "^1.8.1",
"symfony/finder": "^5.3 | ^6.0",
"symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0",
"unleashedtech/php-coding-standard": "^3.1.1",
"vimeo/psalm": "^4.24.0 || ^5.0.0"
},
"minimum-stability": "beta",
"suggest": {
"symfony/yaml": "v2.3+ required if using the Front Matter extension"
},
"repositories": [
{
"type": "package",
"package": {
"name": "commonmark/commonmark.js",
"version": "0.30.0",
"dist": {
"url": "https://github.com/commonmark/commonmark.js/archive/0.30.0.zip",
"type": "zip"
}
}
},
{
"type": "package",
"package": {
"name": "commonmark/cmark",
"version": "0.30.0",
"dist": {
"url": "https://github.com/commonmark/cmark/archive/0.30.0.zip",
"type": "zip"
}
}
},
{
"type": "package",
"package": {
"name": "github/gfm",
"version": "0.29.0",
"dist": {
"url": "https://github.com/github/cmark-gfm/archive/0.29.0.gfm.9.zip",
"type": "zip"
}
}
}
],
"autoload": {
"psr-4": {
"League\\CommonMark\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"League\\CommonMark\\Tests\\Unit\\": "tests/unit",
"League\\CommonMark\\Tests\\Functional\\": "tests/functional",
"League\\CommonMark\\Tests\\PHPStan\\": "tests/phpstan"
}
},
"scripts": {
"phpcs": "phpcs",
"phpstan": "phpstan analyse",
"phpunit": "phpunit --no-coverage",
"psalm": "psalm --stats",
"test": [
"@phpcs",
"@phpstan",
"@psalm",
"@phpunit"
]
},
"extra": {
"branch-alias": {
"dev-main": "2.5-dev"
}
},
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true,
"dealerdirect/phpcodesniffer-composer-installer": true
},
"sort-packages": true
}
}

View File

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark;
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
/**
* Converts CommonMark-compatible Markdown to HTML.
*/
final class CommonMarkConverter extends MarkdownConverter
{
/**
* Create a new Markdown converter pre-configured for CommonMark
*
* @param array<string, mixed> $config
*/
public function __construct(array $config = [])
{
$environment = new Environment($config);
$environment->addExtension(new CommonMarkCoreExtension());
parent::__construct($environment);
}
public function getEnvironment(): Environment
{
\assert($this->environment instanceof Environment);
return $this->environment;
}
}

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark;
use League\CommonMark\Exception\CommonMarkException;
use League\CommonMark\Output\RenderedContentInterface;
use League\Config\Exception\ConfigurationExceptionInterface;
/**
* Interface for a service which converts content from one format (like Markdown) to another (like HTML).
*/
interface ConverterInterface
{
/**
* @throws CommonMarkException
* @throws ConfigurationExceptionInterface
*/
public function convert(string $input): RenderedContentInterface;
}

View File

@ -0,0 +1,134 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Delimiter;
use League\CommonMark\Node\Inline\AbstractStringContainer;
final class Delimiter implements DelimiterInterface
{
/** @psalm-readonly */
private string $char;
/** @psalm-readonly-allow-private-mutation */
private int $length;
/** @psalm-readonly */
private int $originalLength;
/** @psalm-readonly */
private AbstractStringContainer $inlineNode;
/** @psalm-readonly-allow-private-mutation */
private ?DelimiterInterface $previous = null;
/** @psalm-readonly-allow-private-mutation */
private ?DelimiterInterface $next = null;
/** @psalm-readonly */
private bool $canOpen;
/** @psalm-readonly */
private bool $canClose;
/** @psalm-readonly-allow-private-mutation */
private bool $active;
/** @psalm-readonly */
private ?int $index = null;
public function __construct(string $char, int $numDelims, AbstractStringContainer $node, bool $canOpen, bool $canClose, ?int $index = null)
{
$this->char = $char;
$this->length = $numDelims;
$this->originalLength = $numDelims;
$this->inlineNode = $node;
$this->canOpen = $canOpen;
$this->canClose = $canClose;
$this->active = true;
$this->index = $index;
}
public function canClose(): bool
{
return $this->canClose;
}
public function canOpen(): bool
{
return $this->canOpen;
}
public function isActive(): bool
{
return $this->active;
}
public function setActive(bool $active): void
{
$this->active = $active;
}
public function getChar(): string
{
return $this->char;
}
public function getIndex(): ?int
{
return $this->index;
}
public function getNext(): ?DelimiterInterface
{
return $this->next;
}
public function setNext(?DelimiterInterface $next): void
{
$this->next = $next;
}
public function getLength(): int
{
return $this->length;
}
public function setLength(int $length): void
{
$this->length = $length;
}
public function getOriginalLength(): int
{
return $this->originalLength;
}
public function getInlineNode(): AbstractStringContainer
{
return $this->inlineNode;
}
public function getPrevious(): ?DelimiterInterface
{
return $this->previous;
}
public function setPrevious(?DelimiterInterface $previous): void
{
$this->previous = $previous;
}
}

View File

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Delimiter;
use League\CommonMark\Node\Inline\AbstractStringContainer;
interface DelimiterInterface
{
public function canClose(): bool;
public function canOpen(): bool;
public function isActive(): bool;
public function setActive(bool $active): void;
public function getChar(): string;
public function getIndex(): ?int;
public function getNext(): ?DelimiterInterface;
public function setNext(?DelimiterInterface $next): void;
public function getLength(): int;
public function setLength(int $length): void;
public function getOriginalLength(): int;
public function getInlineNode(): AbstractStringContainer;
public function getPrevious(): ?DelimiterInterface;
public function setPrevious(?DelimiterInterface $previous): void;
}

View File

@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace League\CommonMark\Delimiter;
use League\CommonMark\Delimiter\Processor\DelimiterProcessorCollection;
use League\CommonMark\Delimiter\Processor\DelimiterProcessorInterface;
use League\CommonMark\Node\Inline\Text;
use League\CommonMark\Parser\Inline\InlineParserInterface;
use League\CommonMark\Parser\Inline\InlineParserMatch;
use League\CommonMark\Parser\InlineParserContext;
use League\CommonMark\Util\RegexHelper;
/**
* Delimiter parsing is implemented as an Inline Parser with the lowest-possible priority
*
* @internal
*/
final class DelimiterParser implements InlineParserInterface
{
private DelimiterProcessorCollection $collection;
public function __construct(DelimiterProcessorCollection $collection)
{
$this->collection = $collection;
}
public function getMatchDefinition(): InlineParserMatch
{
return InlineParserMatch::oneOf(...$this->collection->getDelimiterCharacters());
}
public function parse(InlineParserContext $inlineContext): bool
{
$character = $inlineContext->getFullMatch();
$numDelims = 0;
$cursor = $inlineContext->getCursor();
$processor = $this->collection->getDelimiterProcessor($character);
\assert($processor !== null); // Delimiter processor should never be null here
$charBefore = $cursor->peek(-1);
if ($charBefore === null) {
$charBefore = "\n";
}
while ($cursor->peek($numDelims) === $character) {
++$numDelims;
}
if ($numDelims < $processor->getMinLength()) {
return false;
}
$cursor->advanceBy($numDelims);
$charAfter = $cursor->getCurrentCharacter();
if ($charAfter === null) {
$charAfter = "\n";
}
[$canOpen, $canClose] = self::determineCanOpenOrClose($charBefore, $charAfter, $character, $processor);
$node = new Text(\str_repeat($character, $numDelims), [
'delim' => true,
]);
$inlineContext->getContainer()->appendChild($node);
// Add entry to stack to this opener
if ($canOpen || $canClose) {
$delimiter = new Delimiter($character, $numDelims, $node, $canOpen, $canClose);
$inlineContext->getDelimiterStack()->push($delimiter);
}
return true;
}
/**
* @return bool[]
*/
private static function determineCanOpenOrClose(string $charBefore, string $charAfter, string $character, DelimiterProcessorInterface $delimiterProcessor): array
{
$afterIsWhitespace = \preg_match(RegexHelper::REGEX_UNICODE_WHITESPACE_CHAR, $charAfter);
$afterIsPunctuation = \preg_match(RegexHelper::REGEX_PUNCTUATION, $charAfter);
$beforeIsWhitespace = \preg_match(RegexHelper::REGEX_UNICODE_WHITESPACE_CHAR, $charBefore);
$beforeIsPunctuation = \preg_match(RegexHelper::REGEX_PUNCTUATION, $charBefore);
$leftFlanking = ! $afterIsWhitespace && (! $afterIsPunctuation || $beforeIsWhitespace || $beforeIsPunctuation);
$rightFlanking = ! $beforeIsWhitespace && (! $beforeIsPunctuation || $afterIsWhitespace || $afterIsPunctuation);
if ($character === '_') {
$canOpen = $leftFlanking && (! $rightFlanking || $beforeIsPunctuation);
$canClose = $rightFlanking && (! $leftFlanking || $afterIsPunctuation);
} else {
$canOpen = $leftFlanking && $character === $delimiterProcessor->getOpeningCharacter();
$canClose = $rightFlanking && $character === $delimiterProcessor->getClosingCharacter();
}
return [$canOpen, $canClose];
}
}

View File

@ -0,0 +1,214 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
* - (c) Atlassian Pty Ltd
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Delimiter;
use League\CommonMark\Delimiter\Processor\DelimiterProcessorCollection;
use League\CommonMark\Node\Inline\AdjacentTextMerger;
final class DelimiterStack
{
/** @psalm-readonly-allow-private-mutation */
private ?DelimiterInterface $top = null;
public function push(DelimiterInterface $newDelimiter): void
{
$newDelimiter->setPrevious($this->top);
if ($this->top !== null) {
$this->top->setNext($newDelimiter);
}
$this->top = $newDelimiter;
}
private function findEarliest(?DelimiterInterface $stackBottom = null): ?DelimiterInterface
{
$delimiter = $this->top;
while ($delimiter !== null && $delimiter->getPrevious() !== $stackBottom) {
$delimiter = $delimiter->getPrevious();
}
return $delimiter;
}
public function removeDelimiter(DelimiterInterface $delimiter): void
{
if ($delimiter->getPrevious() !== null) {
/** @psalm-suppress PossiblyNullReference */
$delimiter->getPrevious()->setNext($delimiter->getNext());
}
if ($delimiter->getNext() === null) {
// top of stack
$this->top = $delimiter->getPrevious();
} else {
/** @psalm-suppress PossiblyNullReference */
$delimiter->getNext()->setPrevious($delimiter->getPrevious());
}
}
private function removeDelimiterAndNode(DelimiterInterface $delimiter): void
{
$delimiter->getInlineNode()->detach();
$this->removeDelimiter($delimiter);
}
private function removeDelimitersBetween(DelimiterInterface $opener, DelimiterInterface $closer): void
{
$delimiter = $closer->getPrevious();
while ($delimiter !== null && $delimiter !== $opener) {
$previous = $delimiter->getPrevious();
$this->removeDelimiter($delimiter);
$delimiter = $previous;
}
}
public function removeAll(?DelimiterInterface $stackBottom = null): void
{
while ($this->top && $this->top !== $stackBottom) {
$this->removeDelimiter($this->top);
}
}
public function removeEarlierMatches(string $character): void
{
$opener = $this->top;
while ($opener !== null) {
if ($opener->getChar() === $character) {
$opener->setActive(false);
}
$opener = $opener->getPrevious();
}
}
/**
* @param string|string[] $characters
*/
public function searchByCharacter($characters): ?DelimiterInterface
{
if (! \is_array($characters)) {
$characters = [$characters];
}
$opener = $this->top;
while ($opener !== null) {
if (\in_array($opener->getChar(), $characters, true)) {
break;
}
$opener = $opener->getPrevious();
}
return $opener;
}
public function processDelimiters(?DelimiterInterface $stackBottom, DelimiterProcessorCollection $processors): void
{
$openersBottom = [];
// Find first closer above stackBottom
$closer = $this->findEarliest($stackBottom);
// Move forward, looking for closers, and handling each
while ($closer !== null) {
$delimiterChar = $closer->getChar();
$delimiterProcessor = $processors->getDelimiterProcessor($delimiterChar);
if (! $closer->canClose() || $delimiterProcessor === null) {
$closer = $closer->getNext();
continue;
}
$openingDelimiterChar = $delimiterProcessor->getOpeningCharacter();
$useDelims = 0;
$openerFound = false;
$potentialOpenerFound = false;
$opener = $closer->getPrevious();
while ($opener !== null && $opener !== $stackBottom && $opener !== ($openersBottom[$delimiterChar] ?? null)) {
if ($opener->canOpen() && $opener->getChar() === $openingDelimiterChar) {
$potentialOpenerFound = true;
$useDelims = $delimiterProcessor->getDelimiterUse($opener, $closer);
if ($useDelims > 0) {
$openerFound = true;
break;
}
}
$opener = $opener->getPrevious();
}
if (! $openerFound) {
if (! $potentialOpenerFound) {
// Only do this when we didn't even have a potential
// opener (one that matches the character and can open).
// If an opener was rejected because of the number of
// delimiters (e.g. because of the "multiple of 3"
// Set lower bound for future searches for openersrule),
// we want to consider it next time because the number
// of delimiters can change as we continue processing.
$openersBottom[$delimiterChar] = $closer->getPrevious();
if (! $closer->canOpen()) {
// We can remove a closer that can't be an opener,
// once we've seen there's no matching opener.
$this->removeDelimiter($closer);
}
}
$closer = $closer->getNext();
continue;
}
\assert($opener !== null);
$openerNode = $opener->getInlineNode();
$closerNode = $closer->getInlineNode();
// Remove number of used delimiters from stack and inline nodes.
$opener->setLength($opener->getLength() - $useDelims);
$closer->setLength($closer->getLength() - $useDelims);
$openerNode->setLiteral(\substr($openerNode->getLiteral(), 0, -$useDelims));
$closerNode->setLiteral(\substr($closerNode->getLiteral(), 0, -$useDelims));
$this->removeDelimitersBetween($opener, $closer);
// The delimiter processor can re-parent the nodes between opener and closer,
// so make sure they're contiguous already. Exclusive because we want to keep opener/closer themselves.
AdjacentTextMerger::mergeTextNodesBetweenExclusive($openerNode, $closerNode);
$delimiterProcessor->process($openerNode, $closerNode, $useDelims);
// No delimiter characters left to process, so we can remove delimiter and the now empty node.
if ($opener->getLength() === 0) {
$this->removeDelimiterAndNode($opener);
}
// phpcs:disable SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed
if ($closer->getLength() === 0) {
$next = $closer->getNext();
$this->removeDelimiterAndNode($closer);
$closer = $next;
}
}
// Remove all delimiters
$this->removeAll($stackBottom);
}
}

View File

@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
* - (c) Atlassian Pty Ltd
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Delimiter\Processor;
use League\CommonMark\Exception\InvalidArgumentException;
final class DelimiterProcessorCollection implements DelimiterProcessorCollectionInterface
{
/**
* @var array<string,DelimiterProcessorInterface>|DelimiterProcessorInterface[]
*
* @psalm-readonly-allow-private-mutation
*/
private array $processorsByChar = [];
public function add(DelimiterProcessorInterface $processor): void
{
$opening = $processor->getOpeningCharacter();
$closing = $processor->getClosingCharacter();
if ($opening === $closing) {
$old = $this->processorsByChar[$opening] ?? null;
if ($old !== null && $old->getOpeningCharacter() === $old->getClosingCharacter()) {
$this->addStaggeredDelimiterProcessorForChar($opening, $old, $processor);
} else {
$this->addDelimiterProcessorForChar($opening, $processor);
}
} else {
$this->addDelimiterProcessorForChar($opening, $processor);
$this->addDelimiterProcessorForChar($closing, $processor);
}
}
public function getDelimiterProcessor(string $char): ?DelimiterProcessorInterface
{
return $this->processorsByChar[$char] ?? null;
}
/**
* @return string[]
*/
public function getDelimiterCharacters(): array
{
return \array_keys($this->processorsByChar);
}
private function addDelimiterProcessorForChar(string $delimiterChar, DelimiterProcessorInterface $processor): void
{
if (isset($this->processorsByChar[$delimiterChar])) {
throw new InvalidArgumentException(\sprintf('Delim processor for character "%s" already exists', $processor->getOpeningCharacter()));
}
$this->processorsByChar[$delimiterChar] = $processor;
}
private function addStaggeredDelimiterProcessorForChar(string $opening, DelimiterProcessorInterface $old, DelimiterProcessorInterface $new): void
{
if ($old instanceof StaggeredDelimiterProcessor) {
$s = $old;
} else {
$s = new StaggeredDelimiterProcessor($opening, $old);
}
$s->add($new);
$this->processorsByChar[$opening] = $s;
}
public function count(): int
{
return \count($this->processorsByChar);
}
}

View File

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
* - (c) Atlassian Pty Ltd
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Delimiter\Processor;
use League\CommonMark\Exception\InvalidArgumentException;
interface DelimiterProcessorCollectionInterface extends \Countable
{
/**
* Add the given delim processor to the collection
*
* @param DelimiterProcessorInterface $processor The delim processor to add
*
* @throws InvalidArgumentException Exception will be thrown if attempting to add multiple processors for the same character
*/
public function add(DelimiterProcessorInterface $processor): void;
/**
* Returns the delim processor which handles the given character if one exists
*/
public function getDelimiterProcessor(string $char): ?DelimiterProcessorInterface;
/**
* Returns an array of delimiter characters who have associated processors
*
* @return string[]
*/
public function getDelimiterCharacters(): array;
}

View File

@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
* - (c) Atlassian Pty Ltd
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Delimiter\Processor;
use League\CommonMark\Delimiter\DelimiterInterface;
use League\CommonMark\Node\Inline\AbstractStringContainer;
/**
* Interface for a delimiter processor
*/
interface DelimiterProcessorInterface
{
/**
* Returns the character that marks the beginning of a delimited node.
*
* This must not clash with any other processors being added to the environment.
*/
public function getOpeningCharacter(): string;
/**
* Returns the character that marks the ending of a delimited node.
*
* This must not clash with any other processors being added to the environment.
*
* Note that for a symmetric delimiter such as "*", this is the same as the opening.
*/
public function getClosingCharacter(): string;
/**
* Minimum number of delimiter characters that are needed to active this.
*
* Must be at least 1.
*/
public function getMinLength(): int;
/**
* Determine how many (if any) of the delimiter characters should be used.
*
* This allows implementations to decide how many characters to be used
* based on the properties of the delimiter runs. An implementation can also
* return 0 when it doesn't want to allow this particular combination of
* delimiter runs.
*
* @param DelimiterInterface $opener The opening delimiter run
* @param DelimiterInterface $closer The closing delimiter run
*/
public function getDelimiterUse(DelimiterInterface $opener, DelimiterInterface $closer): int;
/**
* Process the matched delimiters, e.g. by wrapping the nodes between opener
* and closer in a new node, or appending a new node after the opener.
*
* Note that removal of the delimiter from the delimiter nodes and detaching
* them is done by the caller.
*
* @param AbstractStringContainer $opener The node that contained the opening delimiter
* @param AbstractStringContainer $closer The node that contained the closing delimiter
* @param int $delimiterUse The number of delimiters that were used
*/
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse): void;
}

View File

@ -0,0 +1,111 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
* - (c) Atlassian Pty Ltd
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Delimiter\Processor;
use League\CommonMark\Delimiter\DelimiterInterface;
use League\CommonMark\Exception\InvalidArgumentException;
use League\CommonMark\Node\Inline\AbstractStringContainer;
/**
* An implementation of DelimiterProcessorInterface that dispatches all calls to two or more other DelimiterProcessors
* depending on the length of the delimiter run. All child DelimiterProcessors must have different minimum
* lengths. A given delimiter run is dispatched to the child with the largest acceptable minimum length. If no
* child is applicable, the one with the largest minimum length is chosen.
*
* @internal
*/
final class StaggeredDelimiterProcessor implements DelimiterProcessorInterface
{
/** @psalm-readonly */
private string $delimiterChar;
/** @psalm-readonly-allow-private-mutation */
private int $minLength = 0;
/**
* @var array<int, DelimiterProcessorInterface>|DelimiterProcessorInterface[]
*
* @psalm-readonly-allow-private-mutation
*/
private array $processors = []; // keyed by minLength in reverse order
public function __construct(string $char, DelimiterProcessorInterface $processor)
{
$this->delimiterChar = $char;
$this->add($processor);
}
public function getOpeningCharacter(): string
{
return $this->delimiterChar;
}
public function getClosingCharacter(): string
{
return $this->delimiterChar;
}
public function getMinLength(): int
{
return $this->minLength;
}
/**
* Adds the given processor to this staggered delimiter processor
*
* @throws InvalidArgumentException if attempting to add another processors for the same character and minimum length
*/
public function add(DelimiterProcessorInterface $processor): void
{
$len = $processor->getMinLength();
if (isset($this->processors[$len])) {
throw new InvalidArgumentException(\sprintf('Cannot add two delimiter processors for char "%s" and minimum length %d', $this->delimiterChar, $len));
}
$this->processors[$len] = $processor;
\krsort($this->processors);
$this->minLength = \min($this->minLength, $len);
}
public function getDelimiterUse(DelimiterInterface $opener, DelimiterInterface $closer): int
{
return $this->findProcessor($opener->getLength())->getDelimiterUse($opener, $closer);
}
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse): void
{
$this->findProcessor($delimiterUse)->process($opener, $closer, $delimiterUse);
}
private function findProcessor(int $len): DelimiterProcessorInterface
{
// Find the "longest" processor which can handle this length
foreach ($this->processors as $processor) {
if ($processor->getMinLength() <= $len) {
return $processor;
}
}
// Just use the first one in our list
$first = \reset($this->processors);
\assert($first instanceof DelimiterProcessorInterface);
return $first;
}
}

View File

@ -0,0 +1,447 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Environment;
use League\CommonMark\Delimiter\DelimiterParser;
use League\CommonMark\Delimiter\Processor\DelimiterProcessorCollection;
use League\CommonMark\Delimiter\Processor\DelimiterProcessorInterface;
use League\CommonMark\Event\DocumentParsedEvent;
use League\CommonMark\Event\ListenerData;
use League\CommonMark\Exception\AlreadyInitializedException;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\ConfigurableExtensionInterface;
use League\CommonMark\Extension\ExtensionInterface;
use League\CommonMark\Extension\GithubFlavoredMarkdownExtension;
use League\CommonMark\Normalizer\SlugNormalizer;
use League\CommonMark\Normalizer\TextNormalizerInterface;
use League\CommonMark\Normalizer\UniqueSlugNormalizer;
use League\CommonMark\Normalizer\UniqueSlugNormalizerInterface;
use League\CommonMark\Parser\Block\BlockStartParserInterface;
use League\CommonMark\Parser\Block\SkipLinesStartingWithLettersParser;
use League\CommonMark\Parser\Inline\InlineParserInterface;
use League\CommonMark\Renderer\NodeRendererInterface;
use League\CommonMark\Util\HtmlFilter;
use League\CommonMark\Util\PrioritizedList;
use League\Config\Configuration;
use League\Config\ConfigurationAwareInterface;
use League\Config\ConfigurationInterface;
use Nette\Schema\Expect;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\EventDispatcher\ListenerProviderInterface;
use Psr\EventDispatcher\StoppableEventInterface;
final class Environment implements EnvironmentInterface, EnvironmentBuilderInterface, ListenerProviderInterface
{
/**
* @var ExtensionInterface[]
*
* @psalm-readonly-allow-private-mutation
*/
private array $extensions = [];
/**
* @var ExtensionInterface[]
*
* @psalm-readonly-allow-private-mutation
*/
private array $uninitializedExtensions = [];
/** @psalm-readonly-allow-private-mutation */
private bool $extensionsInitialized = false;
/**
* @var PrioritizedList<BlockStartParserInterface>
*
* @psalm-readonly
*/
private PrioritizedList $blockStartParsers;
/**
* @var PrioritizedList<InlineParserInterface>
*
* @psalm-readonly
*/
private PrioritizedList $inlineParsers;
/** @psalm-readonly */
private DelimiterProcessorCollection $delimiterProcessors;
/**
* @var array<string, PrioritizedList<NodeRendererInterface>>
*
* @psalm-readonly-allow-private-mutation
*/
private array $renderersByClass = [];
/**
* @var PrioritizedList<ListenerData>
*
* @psalm-readonly-allow-private-mutation
*/
private PrioritizedList $listenerData;
private ?EventDispatcherInterface $eventDispatcher = null;
/** @psalm-readonly */
private Configuration $config;
private ?TextNormalizerInterface $slugNormalizer = null;
/**
* @param array<string, mixed> $config
*/
public function __construct(array $config = [])
{
$this->config = self::createDefaultConfiguration();
$this->config->merge($config);
$this->blockStartParsers = new PrioritizedList();
$this->inlineParsers = new PrioritizedList();
$this->listenerData = new PrioritizedList();
$this->delimiterProcessors = new DelimiterProcessorCollection();
// Performance optimization: always include a block "parser" that aborts parsing if a line starts with a letter
// and is therefore unlikely to match any lines as a block start.
$this->addBlockStartParser(new SkipLinesStartingWithLettersParser(), 249);
}
public function getConfiguration(): ConfigurationInterface
{
return $this->config->reader();
}
/**
* @deprecated Environment::mergeConfig() is deprecated since league/commonmark v2.0 and will be removed in v3.0. Configuration should be set when instantiating the environment instead.
*
* @param array<string, mixed> $config
*/
public function mergeConfig(array $config): void
{
@\trigger_error('Environment::mergeConfig() is deprecated since league/commonmark v2.0 and will be removed in v3.0. Configuration should be set when instantiating the environment instead.', \E_USER_DEPRECATED);
$this->assertUninitialized('Failed to modify configuration.');
$this->config->merge($config);
}
public function addBlockStartParser(BlockStartParserInterface $parser, int $priority = 0): EnvironmentBuilderInterface
{
$this->assertUninitialized('Failed to add block start parser.');
$this->blockStartParsers->add($parser, $priority);
$this->injectEnvironmentAndConfigurationIfNeeded($parser);
return $this;
}
public function addInlineParser(InlineParserInterface $parser, int $priority = 0): EnvironmentBuilderInterface
{
$this->assertUninitialized('Failed to add inline parser.');
$this->inlineParsers->add($parser, $priority);
$this->injectEnvironmentAndConfigurationIfNeeded($parser);
return $this;
}
public function addDelimiterProcessor(DelimiterProcessorInterface $processor): EnvironmentBuilderInterface
{
$this->assertUninitialized('Failed to add delimiter processor.');
$this->delimiterProcessors->add($processor);
$this->injectEnvironmentAndConfigurationIfNeeded($processor);
return $this;
}
public function addRenderer(string $nodeClass, NodeRendererInterface $renderer, int $priority = 0): EnvironmentBuilderInterface
{
$this->assertUninitialized('Failed to add renderer.');
if (! isset($this->renderersByClass[$nodeClass])) {
$this->renderersByClass[$nodeClass] = new PrioritizedList();
}
$this->renderersByClass[$nodeClass]->add($renderer, $priority);
$this->injectEnvironmentAndConfigurationIfNeeded($renderer);
return $this;
}
/**
* {@inheritDoc}
*/
public function getBlockStartParsers(): iterable
{
if (! $this->extensionsInitialized) {
$this->initializeExtensions();
}
return $this->blockStartParsers->getIterator();
}
public function getDelimiterProcessors(): DelimiterProcessorCollection
{
if (! $this->extensionsInitialized) {
$this->initializeExtensions();
}
return $this->delimiterProcessors;
}
/**
* {@inheritDoc}
*/
public function getRenderersForClass(string $nodeClass): iterable
{
if (! $this->extensionsInitialized) {
$this->initializeExtensions();
}
// If renderers are defined for this specific class, return them immediately
if (isset($this->renderersByClass[$nodeClass])) {
return $this->renderersByClass[$nodeClass];
}
/** @psalm-suppress TypeDoesNotContainType -- Bug: https://github.com/vimeo/psalm/issues/3332 */
while (\class_exists($parent ??= $nodeClass) && $parent = \get_parent_class($parent)) {
if (! isset($this->renderersByClass[$parent])) {
continue;
}
// "Cache" this result to avoid future loops
return $this->renderersByClass[$nodeClass] = $this->renderersByClass[$parent];
}
return [];
}
/**
* {@inheritDoc}
*/
public function getExtensions(): iterable
{
return $this->extensions;
}
/**
* Add a single extension
*
* @return $this
*/
public function addExtension(ExtensionInterface $extension): EnvironmentBuilderInterface
{
$this->assertUninitialized('Failed to add extension.');
$this->extensions[] = $extension;
$this->uninitializedExtensions[] = $extension;
if ($extension instanceof ConfigurableExtensionInterface) {
$extension->configureSchema($this->config);
}
return $this;
}
private function initializeExtensions(): void
{
// Initialize the slug normalizer
$this->getSlugNormalizer();
// Ask all extensions to register their components
while (\count($this->uninitializedExtensions) > 0) {
foreach ($this->uninitializedExtensions as $i => $extension) {
$extension->register($this);
unset($this->uninitializedExtensions[$i]);
}
}
$this->extensionsInitialized = true;
// Create the special delimiter parser if any processors were registered
if ($this->delimiterProcessors->count() > 0) {
$this->inlineParsers->add(new DelimiterParser($this->delimiterProcessors), PHP_INT_MIN);
}
}
private function injectEnvironmentAndConfigurationIfNeeded(object $object): void
{
if ($object instanceof EnvironmentAwareInterface) {
$object->setEnvironment($this);
}
if ($object instanceof ConfigurationAwareInterface) {
$object->setConfiguration($this->config->reader());
}
}
/**
* @deprecated Instantiate the environment and add the extension yourself
*
* @param array<string, mixed> $config
*/
public static function createCommonMarkEnvironment(array $config = []): Environment
{
$environment = new self($config);
$environment->addExtension(new CommonMarkCoreExtension());
return $environment;
}
/**
* @deprecated Instantiate the environment and add the extension yourself
*
* @param array<string, mixed> $config
*/
public static function createGFMEnvironment(array $config = []): Environment
{
$environment = new self($config);
$environment->addExtension(new CommonMarkCoreExtension());
$environment->addExtension(new GithubFlavoredMarkdownExtension());
return $environment;
}
public function addEventListener(string $eventClass, callable $listener, int $priority = 0): EnvironmentBuilderInterface
{
$this->assertUninitialized('Failed to add event listener.');
$this->listenerData->add(new ListenerData($eventClass, $listener), $priority);
if (\is_object($listener)) {
$this->injectEnvironmentAndConfigurationIfNeeded($listener);
} elseif (\is_array($listener) && \is_object($listener[0])) {
$this->injectEnvironmentAndConfigurationIfNeeded($listener[0]);
}
return $this;
}
public function dispatch(object $event): object
{
if (! $this->extensionsInitialized) {
$this->initializeExtensions();
}
if ($this->eventDispatcher !== null) {
return $this->eventDispatcher->dispatch($event);
}
foreach ($this->getListenersForEvent($event) as $listener) {
if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {
return $event;
}
$listener($event);
}
return $event;
}
public function setEventDispatcher(EventDispatcherInterface $dispatcher): void
{
$this->eventDispatcher = $dispatcher;
}
/**
* {@inheritDoc}
*
* @return iterable<callable>
*/
public function getListenersForEvent(object $event): iterable
{
foreach ($this->listenerData as $listenerData) {
\assert($listenerData instanceof ListenerData);
/** @psalm-suppress ArgumentTypeCoercion */
if (! \is_a($event, $listenerData->getEvent())) {
continue;
}
yield function (object $event) use ($listenerData) {
if (! $this->extensionsInitialized) {
$this->initializeExtensions();
}
return \call_user_func($listenerData->getListener(), $event);
};
}
}
/**
* @return iterable<InlineParserInterface>
*/
public function getInlineParsers(): iterable
{
if (! $this->extensionsInitialized) {
$this->initializeExtensions();
}
return $this->inlineParsers->getIterator();
}
public function getSlugNormalizer(): TextNormalizerInterface
{
if ($this->slugNormalizer === null) {
$normalizer = $this->config->get('slug_normalizer/instance');
\assert($normalizer instanceof TextNormalizerInterface);
$this->injectEnvironmentAndConfigurationIfNeeded($normalizer);
if ($this->config->get('slug_normalizer/unique') !== UniqueSlugNormalizerInterface::DISABLED && ! $normalizer instanceof UniqueSlugNormalizer) {
$normalizer = new UniqueSlugNormalizer($normalizer);
}
if ($normalizer instanceof UniqueSlugNormalizer) {
if ($this->config->get('slug_normalizer/unique') === UniqueSlugNormalizerInterface::PER_DOCUMENT) {
$this->addEventListener(DocumentParsedEvent::class, [$normalizer, 'clearHistory'], -1000);
}
}
$this->slugNormalizer = $normalizer;
}
return $this->slugNormalizer;
}
/**
* @throws AlreadyInitializedException
*/
private function assertUninitialized(string $message): void
{
if ($this->extensionsInitialized) {
throw new AlreadyInitializedException($message . ' Extensions have already been initialized.');
}
}
public static function createDefaultConfiguration(): Configuration
{
return new Configuration([
'html_input' => Expect::anyOf(HtmlFilter::STRIP, HtmlFilter::ALLOW, HtmlFilter::ESCAPE)->default(HtmlFilter::ALLOW),
'allow_unsafe_links' => Expect::bool(true),
'max_nesting_level' => Expect::type('int')->default(PHP_INT_MAX),
'renderer' => Expect::structure([
'block_separator' => Expect::string("\n"),
'inner_separator' => Expect::string("\n"),
'soft_break' => Expect::string("\n"),
]),
'slug_normalizer' => Expect::structure([
'instance' => Expect::type(TextNormalizerInterface::class)->default(new SlugNormalizer()),
'max_length' => Expect::int()->min(0)->default(255),
'unique' => Expect::anyOf(UniqueSlugNormalizerInterface::DISABLED, UniqueSlugNormalizerInterface::PER_ENVIRONMENT, UniqueSlugNormalizerInterface::PER_DOCUMENT)->default(UniqueSlugNormalizerInterface::PER_DOCUMENT),
]),
]);
}
}

View File

@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Environment;
interface EnvironmentAwareInterface
{
public function setEnvironment(EnvironmentInterface $environment): void;
}

View File

@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Environment;
use League\CommonMark\Delimiter\Processor\DelimiterProcessorInterface;
use League\CommonMark\Exception\AlreadyInitializedException;
use League\CommonMark\Extension\ExtensionInterface;
use League\CommonMark\Node\Node;
use League\CommonMark\Parser\Block\BlockStartParserInterface;
use League\CommonMark\Parser\Inline\InlineParserInterface;
use League\CommonMark\Renderer\NodeRendererInterface;
use League\Config\ConfigurationProviderInterface;
/**
* Interface for building the Environment with any extensions, parsers, listeners, etc. that it may need
*/
interface EnvironmentBuilderInterface extends ConfigurationProviderInterface
{
/**
* Registers the given extension with the Environment
*
* @throws AlreadyInitializedException if the Environment has already been initialized
*/
public function addExtension(ExtensionInterface $extension): EnvironmentBuilderInterface;
/**
* Registers the given block start parser with the Environment
*
* @param BlockStartParserInterface $parser Block parser instance
* @param int $priority Priority (a higher number will be executed earlier)
*
* @return $this
*
* @throws AlreadyInitializedException if the Environment has already been initialized
*/
public function addBlockStartParser(BlockStartParserInterface $parser, int $priority = 0): EnvironmentBuilderInterface;
/**
* Registers the given inline parser with the Environment
*
* @param InlineParserInterface $parser Inline parser instance
* @param int $priority Priority (a higher number will be executed earlier)
*
* @return $this
*
* @throws AlreadyInitializedException if the Environment has already been initialized
*/
public function addInlineParser(InlineParserInterface $parser, int $priority = 0): EnvironmentBuilderInterface;
/**
* Registers the given delimiter processor with the Environment
*
* @param DelimiterProcessorInterface $processor Delimiter processors instance
*
* @throws AlreadyInitializedException if the Environment has already been initialized
*/
public function addDelimiterProcessor(DelimiterProcessorInterface $processor): EnvironmentBuilderInterface;
/**
* Registers the given node renderer with the Environment
*
* @param string $nodeClass The fully-qualified node element class name the renderer below should handle
* @param NodeRendererInterface $renderer The renderer responsible for rendering the type of element given above
* @param int $priority Priority (a higher number will be executed earlier)
*
* @psalm-param class-string<Node> $nodeClass
*
* @return $this
*
* @throws AlreadyInitializedException if the Environment has already been initialized
*/
public function addRenderer(string $nodeClass, NodeRendererInterface $renderer, int $priority = 0): EnvironmentBuilderInterface;
/**
* Registers the given event listener
*
* @param class-string $eventClass Fully-qualified class name of the event this listener should respond to
* @param callable $listener Listener to be executed
* @param int $priority Priority (a higher number will be executed earlier)
*
* @return $this
*
* @throws AlreadyInitializedException if the Environment has already been initialized
*/
public function addEventListener(string $eventClass, callable $listener, int $priority = 0): EnvironmentBuilderInterface;
}

View File

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Environment;
use League\CommonMark\Delimiter\Processor\DelimiterProcessorCollection;
use League\CommonMark\Extension\ExtensionInterface;
use League\CommonMark\Node\Node;
use League\CommonMark\Normalizer\TextNormalizerInterface;
use League\CommonMark\Parser\Block\BlockStartParserInterface;
use League\CommonMark\Parser\Inline\InlineParserInterface;
use League\CommonMark\Renderer\NodeRendererInterface;
use League\Config\ConfigurationProviderInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
interface EnvironmentInterface extends ConfigurationProviderInterface, EventDispatcherInterface
{
/**
* Get all registered extensions
*
* @return ExtensionInterface[]
*/
public function getExtensions(): iterable;
/**
* @return iterable<BlockStartParserInterface>
*/
public function getBlockStartParsers(): iterable;
/**
* @return iterable<InlineParserInterface>
*/
public function getInlineParsers(): iterable;
public function getDelimiterProcessors(): DelimiterProcessorCollection;
/**
* @psalm-param class-string<Node> $nodeClass
*
* @return iterable<NodeRendererInterface>
*/
public function getRenderersForClass(string $nodeClass): iterable;
public function getSlugNormalizer(): TextNormalizerInterface;
}

View File

@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the Symfony EventDispatcher "Event" contract
* - (c) 2018-2019 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Event;
use Psr\EventDispatcher\StoppableEventInterface;
/**
* Base class for classes containing event data.
*
* This class contains no event data. It is used by events that do not pass
* state information to an event handler when an event is raised.
*
* You can call the method stopPropagation() to abort the execution of
* further listeners in your event listener.
*/
abstract class AbstractEvent implements StoppableEventInterface
{
/** @psalm-readonly-allow-private-mutation */
private bool $propagationStopped = false;
/**
* Returns whether further event listeners should be triggered.
*/
final public function isPropagationStopped(): bool
{
return $this->propagationStopped;
}
/**
* Stops the propagation of the event to further event listeners.
*
* If multiple event listeners are connected to the same event, no
* further event listener will be triggered once any trigger calls
* stopPropagation().
*/
final public function stopPropagation(): void
{
$this->propagationStopped = true;
}
}

View File

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Event;
use League\CommonMark\Node\Block\Document;
/**
* Event dispatched when the document has been fully parsed
*/
final class DocumentParsedEvent extends AbstractEvent
{
/** @psalm-readonly */
private Document $document;
public function __construct(Document $document)
{
$this->document = $document;
}
public function getDocument(): Document
{
return $this->document;
}
}

View File

@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Event;
use League\CommonMark\Input\MarkdownInputInterface;
use League\CommonMark\Node\Block\Document;
/**
* Event dispatched when the document is about to be parsed
*/
final class DocumentPreParsedEvent extends AbstractEvent
{
/** @psalm-readonly */
private Document $document;
private MarkdownInputInterface $markdown;
public function __construct(Document $document, MarkdownInputInterface $markdown)
{
$this->document = $document;
$this->markdown = $markdown;
}
public function getDocument(): Document
{
return $this->document;
}
public function getMarkdown(): MarkdownInputInterface
{
return $this->markdown;
}
public function replaceMarkdown(MarkdownInputInterface $markdownInput): void
{
$this->markdown = $markdownInput;
}
}

View File

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Event;
use League\CommonMark\Node\Block\Document;
/**
* Event dispatched just before rendering begins
*/
final class DocumentPreRenderEvent extends AbstractEvent
{
/** @psalm-readonly */
private Document $document;
/** @psalm-readonly */
private string $format;
public function __construct(Document $document, string $format)
{
$this->document = $document;
$this->format = $format;
}
public function getDocument(): Document
{
return $this->document;
}
public function getFormat(): string
{
return $this->format;
}
}

View File

@ -0,0 +1,42 @@
<?php
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace League\CommonMark\Event;
use League\CommonMark\Output\RenderedContentInterface;
final class DocumentRenderedEvent extends AbstractEvent
{
private RenderedContentInterface $output;
public function __construct(RenderedContentInterface $output)
{
$this->output = $output;
}
/**
* @psalm-mutation-free
*/
public function getOutput(): RenderedContentInterface
{
return $this->output;
}
/**
* @psalm-external-mutation-free
*/
public function replaceOutput(RenderedContentInterface $output): void
{
$this->output = $output;
}
}

View File

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Event;
/**
* @internal
*
* @psalm-immutable
*/
final class ListenerData
{
/** @var class-string */
private string $event;
/** @var callable */
private $listener;
/**
* @param class-string $event
*/
public function __construct(string $event, callable $listener)
{
$this->event = $event;
$this->listener = $listener;
}
/**
* @return class-string
*/
public function getEvent(): string
{
return $this->event;
}
public function getListener(): callable
{
return $this->listener;
}
}

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Exception;
class AlreadyInitializedException extends LogicException implements CommonMarkException
{
}

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Exception;
/**
* Marker interface for all exceptions thrown by this library.
*/
interface CommonMarkException extends \Throwable
{
}

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Exception;
class IOException extends \RuntimeException implements CommonMarkException
{
}

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Exception;
class InvalidArgumentException extends \InvalidArgumentException implements CommonMarkException
{
}

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Exception;
class LogicException extends \LogicException implements CommonMarkException
{
}

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Exception;
class MissingDependencyException extends \RuntimeException implements CommonMarkException
{
}

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Exception;
final class UnexpectedEncodingException extends \RuntimeException implements CommonMarkException
{
}

View File

@ -0,0 +1,32 @@
<?php
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
* (c) 2015 Martin Hasoň <martin.hason@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace League\CommonMark\Extension\Attributes;
use League\CommonMark\Environment\EnvironmentBuilderInterface;
use League\CommonMark\Event\DocumentParsedEvent;
use League\CommonMark\Extension\Attributes\Event\AttributesListener;
use League\CommonMark\Extension\Attributes\Parser\AttributesBlockStartParser;
use League\CommonMark\Extension\Attributes\Parser\AttributesInlineParser;
use League\CommonMark\Extension\ExtensionInterface;
final class AttributesExtension implements ExtensionInterface
{
public function register(EnvironmentBuilderInterface $environment): void
{
$environment->addBlockStartParser(new AttributesBlockStartParser());
$environment->addInlineParser(new AttributesInlineParser());
$environment->addEventListener(DocumentParsedEvent::class, [new AttributesListener(), 'processDocument']);
}
}

Some files were not shown because too many files have changed in this diff Show More